docker-selenium 发布记录解读:Firefox 143.0.4 + GeckoDriver 0.37.1 + Selenium Grid 4.48.0 镜像标签全解析

原创2026-10-03 19:11:421,428 阅读
文章标签:测试后端云原生容器编排可观测性

docker-selenium 发布记录解读:Firefox 143.0.4 + GeckoDriver 0.37.1 + Selenium Grid 4.48.0 镜像标签全解析

本篇技术指南以 CHANGELOG/4.48.0/firefox_143.md 记录的真实发布日志为线索,完整解读 docker-selenium 项目为 Firefox 143.0.4 生成的全部镜像标签及其命名规律,并结合仓库中的打标签脚本与 Dockerfile 源码,说明版本探测、短版本推导、多标签生成与推送的底层实现。读完本文,你将能够读懂任意一份浏览器 changelog 文件,并准确选择适合自己的 selenium/node-firefox 与 selenium/standalone-firefox 镜像标签。

一、这份 changelog 记录了什么

CHANGELOG/4.48.0/firefox_143.md 是 docker-selenium 项目版本矩阵中的一个明细页,由 CHANGELOG/generate-matrix-readme.py 扫描各浏览器版本目录自动生成入口,并通过 CHANGELOG/README.md 中的版本矩阵表链接到该文件。矩阵表中,Grid 版本 4.48.0 与 Firefox 143 相交的 ✓ 即指向本文件。

该文件全文是一次真实执行 tag_and_push_browser_images.sh 的输出记录,核心信息如下:

./tag_and_push_browser_images.sh 4.48.0 20260909 selenium false firefox true
Tagging images for browser firefox, version 4.48.0, build date 20260909, namespace selenium
Selenium Grid version -> 4.48.0-20260909
Firefox version -> 143.0.4
Short Firefox version -> 143.0
GeckoDriver version -> 0.37.1
Short GeckoDriver version -> 0.37

这一行命令对应的正是 Makefile 中的 tag_and_push_firefox_images 目标:

tag_and_push_firefox_images:
	./tag_and_push_browser_images.sh $(VERSION) $(BUILD_DATE) $(NAMESPACE) $(PUSH_IMAGE) firefox $(RELEASE_OLD_VERSION)

其中 RELEASE_OLD_VERSION 在 Makefile 中默认定义为 false,而本次执行传入了 true,表示这是一次"保留旧版本标签"的发布操作(脚本只在 RELEASE_OLD_VERSION=false 时追加不含构建日期的短标签,详见下文第三节)。

二、本次发布涉及的版本组合

根据输出记录,本次打标签的镜像涉及三个版本维度:

组件 完整版本 短版本(取前两段)
Selenium Grid 4.48.0(构建日期 20260909) —
Firefox 143.0.4 143.0
GeckoDriver 0.37.1 0.37

三个组件版本都不是"写死"的,而是脚本在运行时从已构建好的镜像里实时探测出来的。以 firefox 分支为例,tag_and_push_browser_images.sh 中通过 docker run 进入 selenium/node-firefox:4.48.0-20260909 容器执行命令并解析输出:

FIREFOX_VERSION=$(docker run --rm ${NAMESPACE}/node-firefox:${TAG_VERSION} firefox --version | awk '{print $3}')
FIREFOX_SHORT_VERSION="$(short_version ${FIREFOX_VERSION})"
GECKODRIVER_VERSION=$(docker run --rm ${NAMESPACE}/node-firefox:${TAG_VERSION} geckodriver --version | awk 'NR==1{print $2}')
GECKODRIVER_SHORT_VERSION="$(short_version ${GECKODRIVER_VERSION})"

short_version() 函数实现为将版本号按 . 切分后取前两段:

function short_version() {
  local __long_version=$1
  local __version_split=(${__long_version//./ })
  echo "${__version_split[0]}.${__version_split[1]}"
}

这也解释了输出中 Short Firefox version -> 143.0 与 Short GeckoDriver version -> 0.37 的来源:143.0.4 截取为 143.0,0.37.1 截取为 0.37。

三、20 个镜像标签的完整清单与命名规律

firefox_143.md 记录本次共生成 20 条 Tagged 输出,覆盖 node-firefox 与 standalone-firefox 两个镜像仓库。先看脚本中标签组的定义逻辑(tag_and_push_browser_images.sh firefox 分支):

FIREFOX_TAGS=(
  ${FIREFOX_VERSION}-geckodriver-${GECKODRIVER_VERSION}-grid-${TAG_VERSION}
  ${FIREFOX_VERSION}-geckodriver-${GECKODRIVER_VERSION}-${BUILD_DATE}
  ${FIREFOX_VERSION}-${BUILD_DATE}
  ${FIREFOX_SHORT_VERSION}-geckodriver-${GECKODRIVER_SHORT_VERSION}-grid-${TAG_VERSION}
  ${FIREFOX_SHORT_VERSION}-geckodriver-${GECKODRIVER_SHORT_VERSION}-${BUILD_DATE}
  ${FIREFOX_SHORT_VERSION}-${BUILD_DATE}
)

由于本次 RELEASE_OLD_VERSION=true,不追加"无构建日期"的 4 个标签;随后对每个标签同时打 node-firefox 与 standalone-firefox 两个镜像,6 个标签 × 2 个镜像 = 12 个 Tagged 输出。但日志实际有 20 行,原因是 retag 采用 docker tag(本地别名)加 docker push(当 PUSH_IMAGE=true 时)的方式,而本次 PUSH_IMAGE=false,因此 12 个 tag 对应 12 行输出……此处日志中 Tagged selenium/node-firefox:... 与 Tagged selenium/standalone-firefox:... 各出现 10 次,即每个镜像 10 个标签。逐条整理如下:

selenium/node-firefox(10 个标签)

# 标签
1 143.0.4-geckodriver-0.37.1-grid-4.48.0-20260909
2 143.0.4-geckodriver-0.37.1-20260909
3 143.0.4-20260909
4 143.0-geckodriver-0.37-grid-4.48.0-20260909
5 143.0-geckodriver-0.37-20260909
6 143.0-20260909
7 143.0.4-geckodriver-0.37.1
8 143.0.4
9 143.0-geckodriver-0.37
10 143.0

selenium/standalone-firefox(10 个标签)

# 标签
1 143.0.4-geckodriver-0.37.1-grid-4.48.0-20260909
2 143.0.4-geckodriver-0.37.1-20260909
3 143.0.4-20260909
4 143.0-geckodriver-0.37-grid-4.48.0-20260909
5 143.0-geckodriver-0.37-20260909
6 143.0-20260909
7 143.0.4-geckodriver-0.37.1
8 143.0.4
9 143.0-geckodriver-0.37
10 143.0

标签命名遵循 docs/docker-hub/node-firefox.md 中描述的约定,由"浏览器版本 + 驱动版本 + Grid 版本 + 构建日期"各维度组合而成:

selenium/node-firefox:<browserVersion>-<browserDriver>-<browserDriverVersion>-<Major>.<Minor>.<Patch>-<YYYYMMDD>
  • 完整版本标签(含 patch 号):如 143.0.4-geckodriver-0.37.1-grid-4.48.0-20260909,适合精确复现测试环境;
  • 短版本标签(仅主次版本):如 143.0-geckodriver-0.37-grid-4.48.0-20260909,方便语义化跟踪 Firefox/GeckoDriver 大版本线;
  • 纯构建日期标签:如 143.0.4-20260909、143.0-20260909,用于快速锁定某天的发布;
  • 无日期标签(仅当 RELEASE_OLD_VERSION=false 时追加):如 143.0.4、143.0,指向该浏览器版本线的最新发布。

四、retag 与发布链路:从本地标签到多架构镜像

日志中的每条 Tagged 都来自脚本底层的 retag() 函数(tag_and_push_browser_images.sh):

function retag() {
  local __image=$1
  local __tag=$2
  local __source="${NAMESPACE}/${__image}:${TAG_VERSION}"

  if [ "${PROMOTE_TAGS}" = "true" ]; then
    docker buildx imagetools create --tag "${NAMESPACE}/${__image}:${__tag}" "${__source}"
    echo "Tagged ${NAMESPACE}/${__image}:${__tag}"
    return
  fi

  docker tag "${__source}" "${NAMESPACE}/${__image}:${__tag}"
  echo "Tagged ${NAMESPACE}/${__image}:${__tag}"
  if [ "${PUSH_IMAGE}" = true ]; then
    docker push "${NAMESPACE}/${__image}:${__tag}"
  fi
}

函数语义值得注意:

  • 所有浏览器标签的源镜像都是 selenium/node-firefox:4.48.0-20260909(即 TAG_VERSION 标签),打标签不会重新构建镜像,只是给同一个镜像内容增加别名,因此多个标签指向同一个镜像 digest;
  • PUSH_IMAGE=false 时只做本地 docker tag,日志输出 20 行 Tagged 但不会推送;发布阶段通过 Makefile 将 PUSH_IMAGE 置为 true 后,每个标签才会执行 docker push;
  • 当 PROMOTE_TAGS=true(发布直接提升测试过的镜像而非重新构建)时,改用 docker buildx imagetools create 在 registry 与 registry 之间直接复制 manifest index,从而保留多架构特性——这也是脚本注释中特别强调的:docker pull 只能带回 runner 自身架构,而 imagetools 作用在 index 层面,registry 到 registry 复制,保证 release 标签的多架构完整性。

在本地环境验证镜像内容,可以使用 firefox_upgrade_version 目标(Makefile)中同样的探测命令:

docker run --rm selenium/standalone-firefox:4.48.0-20260909 /opt/selenium/selenium-server.jar info --version
docker run --rm selenium/standalone-firefox:4.48.0-20260909 firefox --version
docker run --rm selenium/standalone-firefox:4.48.0-20260909 geckodriver --version

五、版本从哪来:NodeFirefox 镜像的构建依据

浏览器与驱动的具体版本由 NodeFirefox/Dockerfile 在构建期决定,发布日志中的 143.0.4 与 0.37.1 即来自以下构建参数与安装逻辑:

Firefox 安装。 构建参数 FIREFOX_VERSION(默认 latest)决定安装方式:

  • 对 latest、beta-latest、nightly-latest、devedition-latest、esr-latest,以及主版本 ≥ 136 的数值版本,优先通过 install-firefox-apt.sh 走 apt 仓库安装(对 amd64 或最新版分支);
  • 对其他数值版本,构造 Mozilla CDN 下载地址 https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-$ARCH/en-US/firefox-$FIREFOX_VERSION.deb,若返回 404 则回退到 .tar.bz2 包,由 NodeFirefox/install-firefox-package.sh 完成下载、解压与符号链接(ln -fs /opt/firefox-.../firefox /usr/bin/firefox);
  • 之后调用 NodeFirefox/get_lang_package.sh 从 https://ftp.mozilla.org/pub/firefox/releases/$VERSION/linux-x86_64/xpi/ 下载该版本对应的语言包到 distribution/extensions 目录;
  • 最后 apt-get upgrade -yq 统一升级依赖,修复 Firefox 依赖库的已知 CVE。

GeckoDriver 安装。 构建参数 GECKODRIVER_VERSION(默认 latest)先解析 GitHub release 的最新版本,再按架构选择 linux64 或 linux-aarch64 归档下载,解压后安装为 /opt/geckodriver-$GK_VERSION,并通过软链接暴露为全局命令 geckodriver。

浏览器信息固化。 Dockerfile 在构建期把浏览器元数据写入镜像:

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": "${SE_BROWSER_BINARY_LOCATION:-/usr/bin/firefox}"}}' > /opt/selenium/browsers/firefox/binary_location

并预设了 SE_OTEL_SERVICE_NAME="selenium-node-firefox" 与 SE_NODE_ENABLE_MANAGED_DOWNLOADS="true" 两个环境变量,前者用于链路追踪的服务命名,后者启用 Selenium Grid 4 的受管下载功能。

六、如何使用这些镜像标签

根据 docs/docker-hub/node-firefox.md 的用法,将 Node 接入 Grid 时建议携带 --shm-size=2g 使用宿主机共享内存:

docker network create grid

docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:latest

docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \
    --shm-size="2g" \
    selenium/node-firefox:143.0-geckodriver-0.37-grid-4.48.0-20260909

将测试指向 http://localhost:4444 即可运行 WebDriver 测试;需要观察容器内浏览器画面时可访问 http://localhost:7900/?autoconnect=1&resize=scale&password=secret(noVNC)。使用 standalone 镜像则无需 Hub:

docker run -d -p 4444:4444 --shm-size="2g" \
    selenium/standalone-firefox:143.0.4-geckodriver-0.37.1-grid-4.48.0-20260909

选择标签的建议:CI 回归场景优先使用包含完整 patch 与构建日期的标签(如 143.0.4-geckodriver-0.37.1-grid-4.48.0-20260909)以精确复现;需要跟随某个浏览器大版本线时使用短版本标签(如 143.0)。同时注意 CHANGELOG/README.md 的官方说明:项目并未对"每个 Grid 版本 × 每个浏览器版本"的每一种组合都做完整回归测试,用户应根据自身测试需求评估后选择组合。

七、版本维护机制:changelog 如何生成与归档

本文件所在的 4.48.0 目录由 CHANGELOG/generate-matrix-readme.py 维护:脚本按 ([\w-]+)_(\d+)\.md 模式扫描各版本目录下的 changelog 文件,汇总出"Grid 版本 × 浏览器版本"矩阵并写入 CHANGELOG/README.md;当出现更新的 Grid 版本时,旧版本目录会被移动到 archived/ 下保留。这也意味着:

  • 每个浏览器版本的 changelog 文件是该次发布打标签过程的真实留痕,是排查"某个标签是否存在/指向哪个版本"的第一手依据;
  • 若一个 Grid 版本同时发布了多个 Firefox 版本(如 4.48.0 同时存在 firefox_142.md、firefox_143.md 乃至更新的版本文件),意味着该 Grid 版本支持对应的多条浏览器版本线,可在矩阵表中横向对照选择。
登录后查看全文
docker-selenium