docker-selenium 发布记录解读:Firefox 143.0.4 + GeckoDriver 0.37.1 + Selenium Grid 4.48.0 镜像标签全解析
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 版本支持对应的多条浏览器版本线,可在矩阵表中横向对照选择。