From df337582978b39993a93de325446a276c70df2cd Mon Sep 17 00:00:00 2001 From: Viet Nguyen Duc Date: Fri, 5 Sep 2025 09:25:24 +0700 Subject: [PATCH 1/2] Docker: Support switch binary Chrome/Chromium in Node/Standalone all browsers image Signed-off-by: Viet Nguyen Duc --- ENV_VARIABLES.md | 10 +++--- NodeBase/generate_config | 9 +++--- NodeChrome/Dockerfile | 2 +- NodeChromium/Dockerfile | 2 +- NodeEdge/Dockerfile | 2 +- NodeFirefox/Dockerfile | 2 +- README.md | 31 +++++++++++++------ .../generate_list_env_vars/description.yaml | 22 ++++++++++--- 8 files changed, 52 insertions(+), 28 deletions(-) diff --git a/ENV_VARIABLES.md b/ENV_VARIABLES.md index 35b7ec0e7..46ef42814 100644 --- a/ENV_VARIABLES.md +++ b/ENV_VARIABLES.md @@ -110,8 +110,8 @@ | SE_NODE_MAX_SESSIONS | 1 | | | | SE_NODE_OVERRIDE_MAX_SESSIONS | false | | | | SE_OFFLINE | true | Selenium Manager offline mode, use the browser and driver pre-configured in the image | | -| SE_NODE_BROWSER_VERSION | stable | Overwrite the default browserVersion in Node stereotype | | -| SE_NODE_PLATFORM_NAME | Linux | Overwrite the default platformName in Node stereotype | | +| SE_NODE_BROWSER_VERSION | stable | Overwrite the default browserVersion in Node stereotype. By default, it is short version of current browser installed in Node. For example `139.0` | | +| SE_NODE_PLATFORM_NAME | Linux | Overwrite the default platformName in Node stereotype. By default, it is `Linux` | | | SE_SUPERVISORD_LOG_LEVEL | info | | | | SE_SUPERVISORD_CHILD_LOG_DIR | /tmp | | | | SE_SUPERVISORD_LOG_FILE | /tmp/supervisord.log | | | @@ -119,9 +119,9 @@ | SE_SUPERVISORD_START_RETRIES | 5 | | | | SE_RECORD_AUDIO | false | Flag to enable recording the audio source (default is Pulse Audio input) | | | SE_AUDIO_SOURCE | -f pulse -ac 2 -i default | FFmpeg arguments to record the audio source | | -| SE_BROWSER_BINARY_LOCATION | | | | +| SE_BROWSER_BINARY_LOCATION | | Browser binary location set to Node driver configuration. This helpful in case you customize on top of official Docker image to install another browser in other path and still using GENERATE_CONFIG=true (where enforce detect-drivers = false and controlled by our config logic). By default in corresponding browser, default path would be `/usr/bin/google-chrome`, `/usr/bin/chromium`, `/usr/bin/firefox`, `/usr/bin/microsoft-edge`. Example usage: `SE_BROWSER_BINARY_LOCATION=/opt/google-chrome` | | | SE_NODE_BROWSER_NAME | | | | -| SE_NODE_CONTAINER_NAME | | | | +| SE_NODE_CONTAINER_NAME | | Set a unique name to identify the Node is running in which container (via session capabilities `se:containerName`). This is helpful when deploying Node in Kubernetes cluster, where is able to use metadata pod name set to this env variable. By default, it is the `$(hostname)` (a.k.a container id could be seen via `docker ps`) | | | SE_NODE_HOST | | | | | SE_NODE_RELAY_BROWSER_NAME | | | | | SE_NODE_RELAY_MAX_SESSIONS | | | | @@ -131,7 +131,7 @@ | SE_NODE_RELAY_STATUS_ENDPOINT | | | | | SE_NODE_RELAY_URL | | | | | SE_NODE_STEREOTYPE | | Capabilities in JSON string to overwrite the default Node stereotype | | -| SE_NODE_STEREOTYPE_EXTRA | | Extra capabilities in JSON string that wants to merge to the default Node stereotype | | +| SE_NODE_STEREOTYPE_EXTRA | | Extra capabilities in JSON string that wants to merge to the default Node stereotype. This is helpful when you want to retain the default Node stereotype and append additional capabilities. Example usage `SE_NODE_STEREOTYPE_EXTRA={"myApp:version":"beta","myApp:publish":"public"}` | | | SE_SESSIONS_MAP_EXTERNAL_HOSTNAME | | | | | SE_SESSIONS_MAP_EXTERNAL_IMPLEMENTATION | | | | | SE_SESSIONS_MAP_EXTERNAL_JDBC_PASSWORD | | | | diff --git a/NodeBase/generate_config b/NodeBase/generate_config index c141f9187..fc0910f5c 100755 --- a/NodeBase/generate_config +++ b/NodeBase/generate_config @@ -144,16 +144,17 @@ if [ -d "/opt/selenium/browsers" ]; then if [ -f "${browser_dir}version" ] && [ "${SE_NODE_BROWSER_VERSION,,}" = "stable" ]; then SE_NODE_BROWSER_VERSION=$(short_version "$(cat "${browser_dir}version")") fi - if [ -f "${browser_dir}binary_location" ] && [ -z "${SE_BROWSER_BINARY_LOCATION}" ]; then - SE_BROWSER_BINARY_LOCATION=$(cat "${browser_dir}binary_location") + if [ -f "${browser_dir}binary_location" ]; then + BINARY_LOCATION=$(cat "${browser_dir}binary_location") + BINARY_LOCATION=$(echo "$BINARY_LOCATION" | SE_BROWSER_BINARY_LOCATION=${SE_BROWSER_BINARY_LOCATION} envsubst) fi SE_NODE_CONTAINER_NAME="${SE_NODE_CONTAINER_NAME:-$(hostname)}" # 'browserName' is mandatory for default stereotype if [[ -z "${SE_NODE_STEREOTYPE}" ]] && [[ -n "${SE_NODE_BROWSER_NAME}" ]] && ([[ -z "${SE_NODE_RELAY_URL}" ]] || [[ "${SE_NODE_RELAY_ONLY}" = "false" ]]); then SE_NODE_STEREOTYPE="{\"browserName\": \"${SE_NODE_BROWSER_NAME}\", \"browserVersion\": \"${SE_NODE_BROWSER_VERSION}\", \"platformName\": \"${SE_NODE_PLATFORM_NAME}\", \"se:containerName\": \"${SE_NODE_CONTAINER_NAME}\", \"container:hostname\": \"$(hostname)\"}" - if [[ -n "${SE_BROWSER_BINARY_LOCATION}" ]]; then - SE_NODE_STEREOTYPE="$(python3 /opt/bin/json_merge.py "${SE_NODE_STEREOTYPE}" "${SE_BROWSER_BINARY_LOCATION}")" + if [[ -n "${BINARY_LOCATION}" ]]; then + SE_NODE_STEREOTYPE="$(python3 /opt/bin/json_merge.py "${SE_NODE_STEREOTYPE}" "${BINARY_LOCATION}")" fi else SE_NODE_STEREOTYPE="${SE_NODE_STEREOTYPE}" diff --git a/NodeChrome/Dockerfile b/NodeChrome/Dockerfile index a85398273..c0ec9022c 100644 --- a/NodeChrome/Dockerfile +++ b/NodeChrome/Dockerfile @@ -52,7 +52,7 @@ USER ${SEL_UID} RUN mkdir -p /opt/selenium/browsers/chrome \ && echo "chrome" > /opt/selenium/browsers/chrome/name \ && google-chrome --version | awk '{print $3}' > /opt/selenium/browsers/chrome/version \ - && echo '{"goog:chromeOptions": {"binary": "/usr/bin/google-chrome"}}' > /opt/selenium/browsers/chrome/binary_location + && echo '{"goog:chromeOptions": {"binary": "${SE_BROWSER_BINARY_LOCATION:-/usr/bin/google-chrome}"}}' > /opt/selenium/browsers/chrome/binary_location ENV SE_OTEL_SERVICE_NAME="selenium-node-chrome" \ SE_NODE_ENABLE_MANAGED_DOWNLOADS="true" diff --git a/NodeChromium/Dockerfile b/NodeChromium/Dockerfile index 67371b0b0..c793f1953 100644 --- a/NodeChromium/Dockerfile +++ b/NodeChromium/Dockerfile @@ -46,7 +46,7 @@ USER ${SEL_UID} RUN mkdir -p /opt/selenium/browsers/chrome \ && echo "chrome" > /opt/selenium/browsers/chrome/name \ && chromium --version | awk '{print $2}' > /opt/selenium/browsers/chrome/version \ - && echo '{"goog:chromeOptions": {"binary": "/usr/bin/chromium"}}' > /opt/selenium/browsers/chrome/binary_location + && echo '{"goog:chromeOptions": {"binary": "${SE_BROWSER_BINARY_LOCATION:-/usr/bin/chromium}"}}' > /opt/selenium/browsers/chrome/binary_location ENV SE_OTEL_SERVICE_NAME="selenium-node-chrome" \ SE_NODE_ENABLE_MANAGED_DOWNLOADS="true" diff --git a/NodeEdge/Dockerfile b/NodeEdge/Dockerfile index d20ac9fd4..495c7eada 100644 --- a/NodeEdge/Dockerfile +++ b/NodeEdge/Dockerfile @@ -69,7 +69,7 @@ USER ${SEL_UID} RUN mkdir -p /opt/selenium/browsers/edge \ && echo "MicrosoftEdge" > /opt/selenium/browsers/edge/name \ && microsoft-edge --version | awk '{print $3}' > /opt/selenium/browsers/edge/version \ - && echo '{"ms:edgeOptions": {"binary": "/usr/bin/microsoft-edge"}}' > /opt/selenium/browsers/edge/binary_location + && echo '{"ms:edgeOptions": {"binary": "${SE_BROWSER_BINARY_LOCATION:-/usr/bin/microsoft-edge}"}}' > /opt/selenium/browsers/edge/binary_location ENV SE_OTEL_SERVICE_NAME="selenium-node-edge" \ SE_NODE_ENABLE_MANAGED_DOWNLOADS="true" diff --git a/NodeFirefox/Dockerfile b/NodeFirefox/Dockerfile index 02ec3fa61..1ec7a437b 100644 --- a/NodeFirefox/Dockerfile +++ b/NodeFirefox/Dockerfile @@ -88,7 +88,7 @@ USER ${SEL_UID} RUN mkdir -p /opt/selenium/browsers/firefox \ && echo "firefox" > /opt/selenium/browsers/firefox/name \ && firefox --version | awk '{print $3}' > /opt/selenium/browsers/firefox/version \ - && echo '{"moz:firefoxOptions": {"binary": "/usr/bin/firefox"}}' > /opt/selenium/browsers/firefox/binary_location + && echo '{"moz:firefoxOptions": {"binary": "${SE_BROWSER_BINARY_LOCATION:-/usr/bin/firefox}"}}' > /opt/selenium/browsers/firefox/binary_location ENV SE_OTEL_SERVICE_NAME="selenium-node-firefox" \ SE_NODE_ENABLE_MANAGED_DOWNLOADS="true" diff --git a/README.md b/README.md index 1ddde2ace..bde0139f3 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Talk to us at https://www.selenium.dev/support/ * [Dev and Beta Channel Browser Images](#dev-and-beta-channel-browser-images) * [Dev and Beta Standalone Mode](#dev-and-beta-standalone-mode) * [Dev and Beta on the Grid](#dev-and-beta-on-the-grid) +* [Single Node/Standalone Image With All Browsers](#single-nodestandalone-image-with-all-browsers) * [Environment Variables](#environment-variables) * [Execution modes](#execution-modes) * [Standalone](#standalone) @@ -160,16 +161,6 @@ The following browsers are available in multi-arch images: | aarch64 (aka arm64/armv8) | ❌ | ✅ | ✅ | ❌ | | armhf (aka arm32/armv7l) | ❌ | ❌ | ❌ | ❌ | - -Accordingly, browsers are available in images `selenium/node-all-browsers` and `selenium/standalone-all-browsers` would be different per architecture. - -| Browser / Arch | x86_64 (aka amd64) | aarch64 (aka arm64/armv8) | -|----------------|--------------------|---------------------------| -| Chrome | ✅ | ❌ | -| Edge | ✅ | ❌ | -| Firefox | ✅ | ✅ | -| Chromium | ❌ | ✅ | - Note: - **Running an AMD64 image under emulation on an ARM64 platform is not recommended due to performance and [stability issues](https://github.com/SeleniumHQ/docker-selenium/issues/2298), or browsers could not launch.** @@ -374,6 +365,26 @@ services: For more information on the Dev and Beta channel container images, see the blog post on [Dev and Beta Channel Browsers via Docker Selenium](https://www.selenium.dev/blog/2022/dev-and-beta-channel-browsers-via-docker-selenium/). +## Single Node/Standalone Image With All Browsers + +From image tag `4.35.0` onwards, a single Node/Standalone image is available with all browsers are pre-installed. Those images are `selenium/standalone-all-browsers` (standalone all in one), `selenium/node-all-browsers` (for Hub-Node mode). + +These two images are suitable for users: +- Prefer a single container with "all-in-one" includes Selenium Grid and popular browsers. +- Don't care about the image size, prefer the convenience. +- Lightweight workload, able to figure out for yourself the resource consumption. + +According to multi-arch support, browsers are available in images `selenium/node-all-browsers` and `selenium/standalone-all-browsers` would be different per architecture. + +| Browser / Arch | x86_64 (aka amd64) | aarch64 (aka arm64/armv8) | +|----------------|--------------------|---------------------------| +| Chrome | ✅ | ❌ | +| Edge | ✅ | ❌ | +| Firefox | ✅ | ✅ | +| Chromium | ✅ | ✅ | + +Both Chrome and Chromium browser binary are available in image arch `linux/amd64`. However, Chrome browser binary is activated by default. In case you want to switch to Chromium browser binary, you can set environment variable `SE_BROWSER_BINARY_LOCATION_CHROME=/usr/bin/chromium`. + ## Environment Variables **Checkout full list of environment variables [here](ENV_VARIABLES.md).** diff --git a/scripts/generate_list_env_vars/description.yaml b/scripts/generate_list_env_vars/description.yaml index a21d2bba4..14c474125 100644 --- a/scripts/generate_list_env_vars/description.yaml +++ b/scripts/generate_list_env_vars/description.yaml @@ -339,10 +339,12 @@ in the image cli: '' - name: SE_NODE_BROWSER_VERSION - description: Overwrite the default browserVersion in Node stereotype + description: Overwrite the default browserVersion in Node stereotype. By default, + it is short version of current browser installed in Node. For example `139.0` cli: '' - name: SE_NODE_PLATFORM_NAME - description: Overwrite the default platformName in Node stereotype + description: Overwrite the default platformName in Node stereotype. By default, + it is `Linux` cli: '' - name: SE_SUPERVISORD_LOG_LEVEL description: '' @@ -366,13 +368,22 @@ description: FFmpeg arguments to record the audio source cli: '' - name: SE_BROWSER_BINARY_LOCATION - description: '' + description: 'Browser binary location set to Node driver configuration. This helpful + in case you customize on top of official Docker image to install another browser + in other path and still using GENERATE_CONFIG=true (where enforce detect-drivers + = false and controlled by our config logic). By default in corresponding browser, + default path would be `/usr/bin/google-chrome`, `/usr/bin/chromium`, `/usr/bin/firefox`, + `/usr/bin/microsoft-edge`. Example usage: `SE_BROWSER_BINARY_LOCATION=/opt/google-chrome`' cli: '' - name: SE_NODE_BROWSER_NAME description: '' cli: '' - name: SE_NODE_CONTAINER_NAME - description: '' + description: Set a unique name to identify the Node is running in which container + (via session capabilities `se:containerName`). This is helpful when deploying + Node in Kubernetes cluster, where is able to use metadata pod name set to this + env variable. By default, it is the `$(hostname)` (a.k.a container id could be + seen via `docker ps`) cli: '' - name: SE_NODE_HOST description: '' @@ -403,7 +414,8 @@ cli: '' - name: SE_NODE_STEREOTYPE_EXTRA description: Extra capabilities in JSON string that wants to merge to the default - Node stereotype + Node stereotype. This is helpful when you want to retain the default Node stereotype + and append additional capabilities. Example usage `SE_NODE_STEREOTYPE_EXTRA={"myApp:version":"beta","myApp:publish":"public"}` cli: '' - name: SE_SESSIONS_MAP_EXTERNAL_HOSTNAME description: '' From cfa108dc0407c6cf6f296ffcf46b006fe8024d0d Mon Sep 17 00:00:00 2001 From: Viet Nguyen Duc Date: Sat, 6 Sep 2025 00:33:17 +0700 Subject: [PATCH 2/2] Reduce CVEs in package [skip ci] Signed-off-by: Viet Nguyen Duc --- Base/Dockerfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Base/Dockerfile b/Base/Dockerfile index bd475b57f..49ef9e8d6 100644 --- a/Base/Dockerfile +++ b/Base/Dockerfile @@ -7,10 +7,10 @@ LABEL org.opencontainers.image.source="https://github.com/${AUTHORS}/docker-sele ARG VERSION ARG RELEASE=selenium-${VERSION} # Default value should be aligned with upstream Selenium (https://github.com/SeleniumHQ/selenium/blob/trunk/MODULE.bazel) -ARG OPENTELEMETRY_VERSION=1.51.0 -ARG GRPC_VERSION=1.73.0 -ARG NETTY_VERSION=4.1.123.Final -ARG CS_VERSION=2.1.24 +ARG OPENTELEMETRY_VERSION=1.53.0 +ARG GRPC_VERSION=1.74.0 +ARG NETTY_VERSION=4.1.126.Final +ARG CS_VERSION=2.1.25-M18 ARG ENVSUBST_VERSION=1.4.5 ARG CURL_VERSION=8.15.0 @@ -144,8 +144,8 @@ RUN --mount=type=secret,id=SEL_PASSWD \ io.opentelemetry:opentelemetry-exporter-otlp:${OPENTELEMETRY_VERSION} \ io.grpc:grpc-netty:${GRPC_VERSION} \ io.netty:netty-codec-http:${NETTY_VERSION} \ - io.netty:netty-handler:${NETTY_VERSION} \ - io.netty:netty-common:${NETTY_VERSION} \ + io.netty:netty-codec-http2:${NETTY_VERSION} \ + io.netty:netty-codec:${NETTY_VERSION} \ > /external_jars/.classpath.txt \ && chmod 664 /external_jars/.classpath.txt ; \ fi \