首页
/ Remotion Lambda Chrome 二进制发布流程:test 区域验证、托管 Layer 同步与全量发布前的把关

Remotion Lambda Chrome 二进制发布流程:test 区域验证、托管 Layer 同步与全量发布前的把关

2026-09-06 10:28:27作者:温玫谨Lighthearted

本文基于 Remotion 仓库中的 Agent Skill 文档 update-chrome-binaries-test-region/SKILL.md,完整还原了 Remotion Lambda 在升级 Chromium 二进制时的标准操作流程:先在 eu-central-1 测试区域发布 5 个托管 Layer,同步 hosted-layers.ts 与仓库内 5 处 Chrome 版本引用,再用 dockerfiles 测试矩阵 对新二进制做端到端验证。读完后,你将掌握一次完整的“test 区域 → 全区域”Chrome 升级操作链,以及每一步在源码中的对应实现。

一、流程总览:为什么先有 test 区域

Remotion Lambda 把渲染所需的 Chromium、字体等二进制以 AWS Lambda Layer 形式托管在自有 AWS 账号 678892195805 下。每次 Chromium 大版本升级不能直接推到所有区域,标准做法是:

  1. AWS setup:把 5 个 Layer 发布到 eu-central-1 测试区域;
  2. Update hosted layers:把发布脚本输出的 ARN/版本写回 hosted-layers.ts
  3. Update Chrome references:同步仓库中 5 处 Chrome 版本引用(下载 URL、License 字符串、3 篇文档);
  4. Docker verification:在本地 Docker 矩阵中用新二进制真实渲染两个测试视频;
  5. 测试区域端到端验证通过之前,不允许继续向所有区域发布。

二、AWS setup:凭证准备与发布命令

2.1 登录与凭证导出

  • 运行 aws sts get-caller-identity,确认当前 AWS CLI 已登录到账号 678892195805;如果不是,需要先让操作者登录。
  • 运行 eval "$(aws configure export-credentials --format env)" 把凭证导出到 shell 环境变量。原因很具体:Lambda client 检查的是 AWS_ACCESS_KEY_ID 环境变量,它不会自己拾取 SSO 或 Identity Center 的凭证
  • 关键的运维细节:eval 与后面执行 bun 的发布命令必须在同一次 shell 调用中完成,因为环境变量不会跨 shell 调用持久化。

2.2 发布命令

packages/lambda 目录下运行:

bun src/admin/make-layer-public.ts --region=eu-central-1

该命令会一次性发布全部 5 个 Layer:fonts、chromium、emoji-apple、emoji-google、cjk

执行成功的判据:标准输出中为 5 个 Layer 各自打印出 LayerArnVersion,最后还有一段完整的 JSON dump,其中已填充刚发布的区域条目。

2.3 源码解析:make-layer-public.ts 做了什么

make-layer-public.ts 的实现与文档完全对应:

  • 区域参数解析parseRegionFlag() 支持 --region=eu-central-1--region eu-central-1 两种写法;指定 --region 时只处理该单个区域(并打印 Filtering to region: ...)。parseSkipFlag() 支持 --skip=region1,region2,被跳过的区域保持旧版本不动——这正是“测试阶段只动 eu-central-1”的底层保障。
  • 区域白名单layerInfo 是一个覆盖 24 个区域的 HostedLayers 结构,不在白名单中的区域会直接抛出 Remotion-hosted Layers are not supported in <region>
  • S3 来源:Layer 内容取自区域桶 remotionlambda-binaries-${region} 中的 remotion-layer-<layer>-v18-arm64.zip,通过 getBucketName() 拼接。
  • 发布与开放:对每个 Layer 依次发送 PublishLayerVersionCommandCompatibleRuntimesnodejs24.xDescription 为当前 Remotion VERSION),再发送 AddLayerVersionPermissionCommand,以 Principal: '*'StatementId: 'public-layer' 开放 lambda:GetLayerVersion 权限,使 Layer 公开可用。
  • 输出:每个 Layer 打印 {LayerArn, Version},全部完成后打印空行与 JSON.stringify(layerInfo, null, 2),也就是文档所说的“最终 JSON dump”。

其中 chromium Layer 的 LicenseInfo 硬编码为 Chromium 149.0.7790.0, compiled from source. ...make-layer-public.ts#L113-L122)——这一行就是后文“更新 Chrome 引用”清单中的第 2 项。

三、Update hosted layers:把发布结果同步回代码

操作方式是复制粘贴,而不是手改

  1. 从发布脚本 stdout 末尾的 JSON dump 中,找到 hosted-layers.ts 对应区域条目的 layerArnversion
  2. 直接替换 hosted-layers.ts 中对应区域的条目,不要手动递增版本号——版本号必须与 AWS 实际返回的 Version 一致。

该文件导出的核心结构(hosted-layers.ts#L3-L17):

  • REMOTION_HOSTED_LAYER_ARN = arn:aws:lambda:*:678892195805:layer:remotion-binaries-*:用户侧用于匹配 Remotion 托管 Layer 的 ARN 通配式;
  • HostedLayers 类型按 HostedLayerRegion(排除 cn-north-1cn-northwest-1)为键,每区域挂一个 AwsLayer[]{layerArn, version} 数组)。

从当前文件内容看,各区域的 5 个 Layer 版本号并不一致(例如 eu-central-1 的 fonts/chromium 已到 64,而多数其他区域 chromium 仍在 30 左右),这正是“测试区域先行、其他区域留在旧版本等待全量 rollout”这一策略在代码中的直接体现。测试阶段(--region=eu-central-1)只更新 eu-central-1 条目;若发布时使用了 --skip=<region>,被跳过区域的条目保持原样。

四、Update Chrome references:5 处版本引用的同步清单

升级 Chromium 时,需要先向操作者确认两个输入:新的 Chrome 版本号(如 149.0.7790.0)和对应的 Playwright revision。若操作者没有提供 Playwright revision,则需到 browsers.json(Playwright 上游的 packages/playwright-core/browsers.json)中按 browserVersion 字段匹配查出。

随后按下表更新 5 处引用:

文件 更新内容
get-chrome-download-url.ts TESTED_VERSIONPLAYWRIGHT_VERSIONPLAYWRIGHT_VERSION 行尾的 // <version> 注释、两条硬编码的 https://remotion.media/chromium-headless-shell-amazon-linux-{arm64,x64}-<version>.zip URL
make-layer-public.ts 传给 PublishLayerVersionCommandChromium <version>, compiled from source. 许可证字符串
runtime.mdx 在“Chrome”版本表中为下一个 Remotion 版本新增一行。下一个版本号从 core/package.json 的当前版本 patch +1 得出
chrome-headless-shell.mdx 版本表新增一行,并更新“Version tracking”一节示例中的版本字符串
ensure-browser.mdx 更新示例代码块中两处 version: '<old>'

4.1 二进制存在性校验(改 URL 之前必须做)

在改动任何下载 URL 之前,先用 curl -sI 验证新二进制确实存在:

  • 两条新的硬编码 amazon-linux-{arm64,x64} URL;
  • 跟随 TESTED_VERSION 拼接出来的两条 chromium-headless-shell-linux-{arm64,x64}-<version>.zip?clearcache URL。

只有全部返回 HTTP 200 才继续;任何一个 404 都说明新构建还没传到 remotion.media,此时应当请操作者先把缺失的构建上传,而不是继续改代码。

4.2 为什么 renderer 里有这么多分支

结合 get-chrome-download-url.ts 的源码可以看到这些 URL 的实际用途:

  • 当前 TESTED_VERSION = '149.0.7790.0'PLAYWRIGHT_VERSION = '1421'get-chrome-download-url.ts#L7-L10);
  • remotion.media 上的二进制构建于 Ubuntu 24.04,要求 glibc 2.35+MINIMUM_GLIBC_FOR_REMOTION_MEDIA = [2, 35]);检测不到足够 glibc 时会回退到 Playwright / Chrome-for-Testing CDN 的构建;
  • Amazon Linux 2023 有特殊分支isAmazonLinux2023() 通过解析 /etc/os-release 识别该发行版,此时返回硬编码的 chromium-headless-shell-amazon-linux-{arm64,x64}-149.0.7790.0.zip——这类构建兼容更旧的 glibc,不要求 2.35。这就是文档要求这两条 URL 必须随版本同步更新的原因:它们是唯一不经过 TESTED_VERSION 模板拼接的下载路径。

五、Docker verification:测试区域的端到端把关

最后一步是在 packages/dockerfiles/ 目录用 ./run.sh 跑 Docker 矩阵测试,验证新 Chrome 二进制。前提:Docker Desktop 先处于运行状态。

5.1 run.sh 做了什么

run.sh 的关键步骤:

  1. 先在 packages/renderer 构建浏览器下载器(bun build-browser-downloader.ts);
  2. 运行 bun pack-cli.tsDocker 镜像安装的是本地 workspace 构建的 @remotion/cli 及其传递依赖,而不是 npm 上已发布的版本。因此 @remotion/renderer 的源码改动在未发布前就会被测到——这保证了测试测的是“即将发布的代码 + 新二进制”;
  3. packages/example 打 bundle:bunx remotion bundle src/browser-test-entry.ts --out-dir ../dockerfiles/bundle
  4. 对矩阵中每个 Dockerfile 执行 build_and_extractdocker build 后用 docker create + docker cp 取出两个视频,最后 docker rm 清理容器。

pack-cli.ts 的机制:从 @remotion/cli 出发遍历所有 workspace:* 传递依赖,对每个包执行 bun pm pack 产出 tarball 到 packages/dockerfiles/tarballs/,再生成 local-cli-package.json——把每个 tarball 同时作为直接依赖overrides 条目写入,从而在传递解析层面强制使用本地构建而非同版本的注册表拷贝。

当前矩阵包含的平台(run.sh#L54-L64):ubuntu24-x86、ubuntu22-x86、debian-x86(通过 --platform linux/amd64 做 x86 模拟构建,便于在 ARM 机器上测试),以及 ubuntu24、ubuntu22、debian 本机构建;al2023 与 nix 目前处于注释停用状态。

5.2 两个测试 composition 与产物

渲染的产物落在 packages/dockerfiles/out/

  • out/<platform>.mp4 —— browser-test 视频:Three.js、WebGL 与编解码(codec)冒烟测试
  • out/<platform>-html-in-canvas.mp4 —— html-in-canvas 视频:实验性的 WICG drawElementImage()canvas.requestPaint() API 验证。

两个 composition 都注册在 BrowserTestRoot.tsxbrowser-test(1280x720,30fps,2 分钟)与 html-in-canvas(1920x1080,30fps,120 帧)。如果未来往矩阵中新增 composition,需要两处登记:在 BrowserTestRoot.tsx 注册 composition,并在 run.sh 中加上对应的 RUN remotion render /usr/app/bundle <id> /usr/app/<filename>.mp4 渲染行以及 docker cp 提取行。

5.3 html-in-canvas 失败时的快速定位

HtmlInCanvas.tsx 中的 isHtmlInCanvasSupported() 运行时检查要求同时存在 4 个 API:

  • ctx.drawElementImageCanvasRenderingContext2D 上);
  • canvas.requestPaint
  • canvas.captureElementImage
  • canvas.transferControlToOffscreen

这些 API 在 Chrome 149+ 传入 --enable-features=CanvasDrawElement 时暴露。据此,文档给出了一个非常实用的排障规则:如果 html-in-canvas 渲染以 "HTML in Canvas is not supported" 失败、而 browser-test 却通过,最可能的原因就是 Chrome 版本不匹配——基础浏览器功能正常,但新的 HTML-in-Canvas 实验 API 不可用,指向二进制版本或 feature flag 的问题。

六、操作要点自查清单

  • [ ] aws sts get-caller-identity 确认账号为 678892195805
  • [ ] eval "$(aws configure export-credentials --format env)"bun src/admin/make-layer-public.ts --region=eu-central-1 在同一次 shell 调用中执行;
  • [ ] stdout 中 5 个 Layer 均有 LayerArnVersion,且末尾 JSON dump 的 eu-central-1 条目已更新;
  • [ ] hosted-layers.ts 仅更新了 eu-central-1(或未被 --skip 的区域),版本号为 AWS 返回值而非手动递增;
  • [ ] curl -sI 对新硬编码 URL 与模板 URL 全部返回 200 后才改动 get-chrome-download-url.ts
  • [ ] 5 处 Chrome 引用(renderer、lambda、3 篇文档)全部同步,runtime.mdx 新版本行对应 core/package.json 的 patch +1;
  • [ ] Docker 矩阵跑完,out/ 下两类视频齐全,browser-testhtml-in-canvas 均正常;
  • [ ] 以上全部通过后,才进入向所有区域发布的阶段。

整套流程的本质是:用一个单区域小范围发布 + 本地 Docker 端到端渲染,把“新 Chromium 二进制 + 未发布 renderer 代码”的组合风险压到最小,验证通过后再全量 rollout。

登录后查看全文
热门项目推荐
相关项目推荐