docker-selenium 4.48.0 发布记录:Firefox 118.0.2 与 GeckoDriver 0.37.1 镜像标签体系全解析
docker-selenium 4.48.0 发布记录:Firefox 118.0.2 与 GeckoDriver 0.37.1 镜像标签体系全解析
本文基于 docker-selenium 仓库的 CHANGELOG/4.48.0/firefox_118.md 发布记录,完整解读该版本为 Firefox 118.0.2 + GeckoDriver 0.37.1 + Selenium Grid 4.48.0 组合生成的全部镜像标签、标签命名规律、底层实现脚本,以及如何根据这些标签在真实测试环境中精确选取所需的 node-firefox 与 standalone-firefox 镜像。读完本文,你将掌握 docker-selenium 浏览器镜像的完整命名约定、tag_and_push_browser_images.sh 的发布原理,以及跨浏览器版本固定、Grid 升级等场景下的镜像选择策略。
一、发布记录概览:一次针对 Firefox 的镜像打标操作
CHANGELOG/4.48.0/firefox_118.md 是一份典型的单浏览器发布记录,本质上是 tag_and_push_browser_images.sh 脚本一次真实执行的输出日志。原文完整记录了执行命令与全部 12 个被打上的镜像标签:
./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 -> 118.0.2
Short Firefox version -> 118.0
GeckoDriver version -> 0.37.1
Short GeckoDriver version -> 0.37
Tagged selenium/node-firefox:118.0.2-geckodriver-0.37.1-grid-4.48.0-20260909
Tagged selenium/standalone-firefox:118.0.2-geckodriver-0.37.1-grid-4.48.0-20260909
Tagged selenium/node-firefox:118.0.2-geckodriver-0.37.1-20260909
Tagged selenium/standalone-firefox:118.0.2-geckodriver-0.37.1-20260909
Tagged selenium/node-firefox:118.0.2-20260909
Tagged selenium/standalone-firefox:20260909
Tagged selenium/node-firefox:118.0-geckodriver-0.37-grid-4.48.0-20260909
Tagged selenium/standalone-firefox:118.0-geckodriver-0.37-grid-4.48.0-20260909
Tagged selenium/node-firefox:118.0-geckodriver-0.37-20260909
Tagged selenium/standalone-firefox:118.0-geckodriver-0.37-20260909
Tagged selenium/node-firefox:118.0-20260909
Tagged selenium/standalone-firefox:118.0-20260909
需要注意两点:一是原文第 13 行实际是 Tagged selenium/standalone-firefox:118.0.2-20260909(上表按脚本生成逻辑补全了完整标签清单),二是该次执行以 RELEASE_OLD_VERSION=true 收尾(第 7 个参数 true),因此没有生成不带构建日期的"浮动"短标签(如 118.0、118.0-geckodriver-0.37 等),这一点将在下文第三节详细解释。
该版本的核心软件组合为:
| 组件 | 版本 | 说明 |
|---|---|---|
| Selenium Grid | 4.48.0-20260909 | Grid 版本号附带构建日期 |
| Firefox | 118.0.2 | 主版本号 118,补丁版本 0.2 |
| GeckoDriver | 0.37.1 | Firefox 的 WebDriver 驱动,主版本 0,次版本 37 |
在 CHANGELOG/README.md 的 Firefox 版本矩阵中,4.48.0 这一行以 ✓ 链接指向 firefox_118.md,与 117、119 等相邻版本并列,说明该发布记录是整个"Grid 版本 × 浏览器版本"矩阵中的一格:项目动机正是"始终供应最新 Selenium Grid 核心的同时,让用户能够固定浏览器版本做跨浏览器测试或规避特定版本的兼容问题",并通过 CHANGELOG/generate-matrix-readme.py 自动扫描各版本目录下的 firefox_*.md 文件来生成这张矩阵表。
二、逐行解读发布日志:版本探测与打标流水线
发布日志的前八行展示了脚本的"探测-计算-打标"三段式工作流,其具体实现在仓库根目录的 tag_and_push_browser_images.sh 中。
2.1 命令行参数
脚本入口(tag_and_push_browser_images.sh)共接收 7 个位置参数:
| 位置 | 变量 | 本次取值 | 含义 |
|---|---|---|---|
| $1 | VERSION | 4.48.0 | Selenium Grid 版本 |
| $2 | BUILD_DATE | 20260909 | 构建日期(YYYYMMDD) |
| $3 | NAMESPACE | selenium | 镜像命名空间 |
| $4 | PUSH_IMAGE | false | 是否 docker push 推送镜像 |
| $5 | BROWSER | firefox | 浏览器类型,进入 case 分支 |
| $6 | RELEASE_OLD_VERSION | true | 是否保留旧版本浮动标签 |
| $7 | PLATFORM | (默认 linux/amd64) | 目标平台架构 |
其中 PUSH_IMAGE=false 说明本次仅做本地 docker tag 打标(retag 函数 仅在 PUSH_IMAGE=true 时执行 docker push),PLATFORM 默认 linux/amd64,chrome 分支还会结合 --platform 运行容器做多架构探测。
2.2 版本探测:在容器内读取真实版本号
firefox 分支(tag_and_push_browser_images.sh)通过临时运行已构建好的 node-firefox 镜像来探测版本,而不是硬编码版本号:
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})"
docker run --rm selenium/node-firefox:4.48.0-20260909 firefox --version在容器内执行 Firefox 自报版本,awk 取第 3 个字段得到118.0.2;geckodriver --version输出首行的第 2 个字段得到0.37.1;short_version()(tag_and_push_browser_images.sh)按.切分后只保留前两段,得到118.0与0.37,用于生成"短版本"标签。
这解释了日志中两行关键输出:Firefox version -> 118.0.2 与 GeckoDriver version -> 0.37.1。这种"以镜像内真实二进制自报版本为准"的方式保证了标签与实际打包内容永远一致,也印证了 NodeFirefox/Dockerfile 中"将浏览器信息落盘供 Grid 上报"的设计(/opt/selenium/browsers/firefox/version 同样由 firefox --version | awk '{print $3}' 生成)。
2.3 标签集合的生成逻辑
firefox 分支按三段式规则构造 FIREFOX_TAGS 数组(tag_and_push_browser_images.sh),并循环对 node-firefox 与 standalone-firefox 两个镜像同时打标:
FIREFOX_TAGS=(
${FIREFOX_VERSION}-geckodriver-${GECKODRIVER_VERSION}-grid-${TAG_VERSION} # 完整版 + 驱动 + Grid + 日期
${FIREFOX_VERSION}-geckodriver-${GECKODRIVER_VERSION}-${BUILD_DATE} # 完整版 + 驱动 + 日期
${FIREFOX_VERSION}-${BUILD_DATE} # 完整版 + 日期
${FIREFOX_SHORT_VERSION}-geckodriver-${GECKODRIVER_SHORT_VERSION}-grid-${TAG_VERSION} # 短版本 + 短驱动 + Grid + 日期
${FIREFOX_SHORT_VERSION}-geckodriver-${GECKODRIVER_SHORT_VERSION}-${BUILD_DATE} # 短版本 + 短驱动 + 日期
${FIREFOX_SHORT_VERSION}-${BUILD_DATE} # 短版本 + 日期
)
由于第 6 个参数 RELEASE_OLD_VERSION=true,脚本跳过以下"旧版本"浮动标签(不带构建日期)的追加逻辑(tag_and_push_browser_images.sh):
118.0.2-geckodriver-0.37.1 # 完整浏览器 + 完整驱动
118.0.2 # 完整浏览器
118.0-geckodriver-0.37 # 短浏览器 + 短驱动
118.0 # 短浏览器
最终,Firefox 118.0.2 的这次发布在 node 与 standalone 两个镜像名下各生成 6 个标签,合计 12 个——这正是原发布记录清单的由来。retag() 内部先以 ${NAMESPACE}/${image}:${TAG_VERSION} 作为源镜像执行 docker tag,日志中 Tagged ... 即来自该函数(tag_and_push_browser_images.sh)。
三、标签命名约定:读懂每一个段位
3.1 标签结构速查表
结合发布日志与 docs/docker-hub/node-firefox.md 的官方说明,node-firefox 与 standalone-firefox 的标签可归纳为下表(<Major>.<Minor>.<Patch> 即 Grid 版本,<YYYYMMDD> 即构建日期):
| 标签模式 | 含义 | 本次实例 |
|---|---|---|
<Major>.<Minor>.<Patch>-<YYYYMMDD> |
Grid 版本 + 构建日期 | 4.48.0-20260909 |
<BrowserVersion>-<YYYYMMDD> |
浏览器完整版本 + 日期 | 118.0.2-20260909 |
<BrowserShort>-<YYYYMMDD> |
浏览器主.次版本 + 日期 | 118.0-20260909 |
<BrowserVersion>-geckodriver-<DriverVersion>-<YYYYMMDD> |
浏览器 + 驱动 + 日期 | 118.0.2-geckodriver-0.37.1-20260909 |
<BrowserShort>-geckodriver-<DriverShort>-<YYYYMMDD> |
短浏览器 + 短驱动 + 日期 | 118.0-geckodriver-0.37-20260909 |
<BrowserShort>-geckodriver-<DriverShort>-grid-<Major>.<Minor>.<Patch>-<YYYYMMDD> |
全量信息标签 | 118.0-geckodriver-0.37-grid-4.48.0-20260909 |
docs/docker-hub/node-firefox.md 中的示例清单还展示了 docker images 输出视角下的完整层级,例如 selenium/node-firefox <BrowserMajor>.<BrowserMinor>-geckodriver-<GeckoDriverMajor>.<GeckoDriverMinor>-grid-<Major>.<Minor>.<Patch>-<YYYYMMDD>,即同一次发布中"Grid 版本"与"浏览器/驱动版本"两条标签线并存——前者用于跟随 Grid 演进,后者用于固定浏览器版本。
3.2 短版本(Short Version)的由来
短版本 118.0 和 0.37 由 short_version() 函数统一生成:按 . 切分版本字符串、仅取前两段。它的意义在于:Firefox 的快速发布节奏下,同主版本号的补丁版本(如 118.0.1、118.0.2)滚动很快,用 <Major>.<Minor> 打标即可在不想锁定具体补丁号时获得该次发布对应的最新补丁,同时配合 -grid-4.48.0-20260909 又不会丢失 Grid 与日期的信息。
3.3 为何本次没有"浮动"短标签
注意 118.0、118.0.2、118.0-geckodriver-0.37 这类不带构建日期的标签本次没有生成,因为第 6 个参数为 RELEASE_OLD_VERSION=true。从脚本注释(tag_and_push_browser_images.sh 等处的分支)可以推断:该参数用于"旧版本(历史浏览器)发布"场景——当为已归档的旧浏览器版本重新发布时,不应让不带日期的浮动标签指向历史构建,以免用户后续 docker pull selenium/node-firefox:118.0 拉到不符合预期的旧镜像;反之,在正常发布新浏览器版本时(RELEASE_OLD_VERSION=false)才会追加这 4 个浮动标签。这也是本文最重要的实操提醒:同一标签在不同发布节奏下可能不存在,选取镜像前应以矩阵 README 与具体发布记录为准。
四、镜像内容溯源:Firefox 118 与 GeckoDriver 在镜像里如何安装
发布记录只描述"打了什么标签",而标签背后"装了什么",由 NodeFirefox/Dockerfile 决定。
4.1 Firefox 安装路径
Dockerfile 支持两类安装方式,均以 FIREFOX_VERSION 构建参数驱动(NodeFirefox/Dockerfile):
- APT 仓库安装:通过 install-firefox-apt.sh 配置 Mozilla 官方 APT 源——导入
packages.mozilla.org的签名密钥并校验指纹35BAA0B33E9EB396F59CA838C0BA5CE6DC6315A3,写入mozilla.list源并设置Pin-Priority: 1000,随后apt install -y firefox。对于latest、beta-latest、nightly-latest、devedition-latest、esr-latest及主版本 ≥ 136 的版本默认走此路径; - 直接下载安装包:
FIREFOX_DOWNLOAD_URL拼接 Mozilla 官方 CDN 地址,优先尝试.deb,404 时回退.tar.bz2;install-firefox-package.sh 负责解包、移动为/opt/firefox-<version>、创建distribution/extensions目录并软链/usr/bin/firefox。
无论哪条路径,都会再执行 apt-get upgrade 修复 Firefox 依赖的已知 CVE,随后通过 get_lang_package.sh 按 FIREFOX_LANG_VERSION 下载语言包。构建完成后容器内会生成 /opt/selenium/browsers/firefox/ 目录,其中 name、version、binary_location 三个文件供 Selenium Grid 上报节点能力(NodeFirefox/Dockerfile)。
4.2 GeckoDriver 安装路径
GeckoDriver 通过构建参数 GECKODRIVER_VERSION 控制(NodeFirefox/Dockerfile):先解析 https://github.com/mozilla/geckodriver/releases/latest 的重定向获取最新版本号,再按架构下载 geckodriver-<version>-linux64 或 linux-aarch64 压缩包,解压到 /opt/geckodriver-<version> 并软链 /usr/bin/geckodriver。docker run ... geckodriver --version 探测到的 0.37.1 即来自这条安装链。
此外,Dockerfile 还为 Node 模式预设了 SE_OTEL_SERVICE_NAME="selenium-node-firefox" 与 SE_NODE_ENABLE_MANAGED_DOWNLOADS="true"(NodeFirefox/Dockerfile),前者用于 OpenTelemetry 链路标识,后者启用 Selenium Manager 的受管下载能力。
五、实操:如何用这些标签跑起 Firefox 118 测试
5.1 使用 node-firefox 接入 Hub/Event Bus
docs/docker-hub/node-firefox.md 给出了 Node 模式的完整启动流程。首先创建网络并启动 Hub:
docker network create grid
docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:latest
随后用本次发布记录中的全量标签启动 Firefox 节点(务必加 --shm-size=2g,浏览器容器需要宿主机共享内存):
docker run -d --net grid \
-e SE_EVENT_BUS_HOST=selenium-hub \
--shm-size="2g" \
selenium/node-firefox:118.0.2-geckodriver-0.37.1-grid-4.48.0-20260909
Windows PowerShell 使用反引号续行:
docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub `
--shm-size="2g" `
selenium/node-firefox:118.0.2-geckodriver-0.37.1-grid-4.48.0-20260909
测试脚本随后指向 http://localhost:4444 即可。容器内画面可通过 http://localhost:7900/?autoconnect=1&resize=scale&password=secret(noVNC)实时查看。使用完毕后清理网络:
docker network rm grid
5.2 使用 standalone-firefox 独立运行
若不需要 Hub/Node 集群,可直接用 standalone 镜像单容器提供完整 Grid 能力,例如:
docker run -d -p 4444:4444 --shm-size="2g" \
selenium/standalone-firefox:118.0.2-geckodriver-0.37.1-20260909
同样,仓库根目录的 docker-compose-v3.yml 也演示了 selenium/node-firefox:4.48.0-20260905 在完整 Grid 编排中的用法,可参考其服务结构搭建包含 EventBus、Sessions、Router、Distributor、SessionQueue 的分布式拓扑。
5.3 按需求选择标签的决策清单
- 跟随最新 Grid + 最新 Firefox:使用
selenium/node-firefox:4.48.0-20260909(Grid 版本线标签),或直接latest; - 固定浏览器完整版本:
selenium/node-firefox:118.0.2-20260909; - 固定浏览器 + 驱动,且要完整可复现:
selenium/node-firefox:118.0.2-geckodriver-0.37.1-grid-4.48.0-20260909(信息最全、最推荐用于 CI 锁版本); - 不想锁补丁号:
118.0-20260909或118.0-geckodriver-0.37-20260909; - 需要 Grid 与浏览器版本线并存:参见 docs/docker-hub/node-firefox.md 的完整标签层级示例。
六、发布记录的定位与延伸阅读
firefox_118.md 只是 CHANGELOG/README.md 矩阵中的一格:4.48.0 行覆盖 Firefox 98~155 共 58 个浏览器版本,每个版本都有同构的发布记录文件(如 firefox_117.md、firefox_119.md,三者除 Firefox 版本号外,Grid 版本与 GeckoDriver 版本完全一致,说明 4.48.0 是"一套 Grid + 一套 GeckoDriver 0.37.1 + 多版本 Firefox"的批量发布)。旧的 Grid 版本会被 generate-matrix-readme.py 自动移入 archived/ 目录并在矩阵中降级展示。这类记录与 ENV_VARIABLES.md(Node 环境变量全集)、docker-compose-v3.yml(完整 Grid 编排示例)一起,构成了理解 docker-selenium 镜像发布与选型的第一手资料。