fix(bot): bake Chrome into the sandbox image at build time - #2416
Conversation
The sandbox egress allowlist only passes GitHub/npm hosts, so agent-browser's runtime Chrome download can never succeed inside a container; the browser has to ship in the image. Install it in the node-source stage (working CA bundle, same pattern as the Node copy) and copy the cache across. Verified with agent-browser doctor's live launch test plus an open/get-text round-trip in the built image.
|
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/auth-atproto
@emdash-cms/blocks
@emdash-cms/cloudflare
@emdash-cms/contentful-to-portable-text
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/plugin-cli
@emdash-cms/plugin-types
@emdash-cms/registry-client
@emdash-cms/registry-lexicons
@emdash-cms/registry-verification
@emdash-cms/sandbox-workerd
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-field-kit
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
There was a problem hiding this comment.
Pull request overview
Updates the emdash-bot sandbox container image so agent-browser can launch a browser in the locked-down runtime environment by pre-installing Chrome for Testing during the image build and copying the resulting cache into the final sandbox stage.
Changes:
- Runs
agent-browser installin thenode-sourcebuild stage (where TLS/network downloads are expected to work). - Copies the resulting
/root/.agent-browsercache into the finalcloudflare/sandboximage so no runtime browser download is needed. - Updates the Dockerfile header comments to reflect that the image now includes a pre-baked browser for repro skills.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | f15551a | Aug 10 2026, 06:49 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-do | f15551a | Aug 10 2026, 06:51 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | f15551a | Aug 10 2026, 06:51 PM |
|
Verification results for the baked Chrome: In the built image (local, linux/amd64): In staging: the container is deployed (version 0ddcaed8). Re-runs of the two previously-blocked cases (#1272, #1124) plus a browser-leaning probe (#1607) all settled cleanly — though each legitimately resolved without the browser under the new needs-info/VFS-first discipline, so the staging-side browser path will get its first real exercise on the next admin investigation that needs the UI. No case attempted a runtime Chrome download (zero egress-block errors in the window). ~ 🤖 Claude Fable 5 |
There was a problem hiding this comment.
The approach is the right fix: the emdash-bot sandbox egress allowlist only permits package/GitHub/npm-ish hosts, so agent-browser install cannot download Chrome for Testing at runtime. Baking the browser into the image during the node-source stage follows the existing multi-stage TLS pattern and solves the reported Chrome install failed failures for repro-admin/repro-public.
I checked the Dockerfile diff, the egress allowlist in infra/emdash-bot/.flue/cloudflare.ts, the repro skill docs, entrypoint.sh, and AGENTS.md conventions. No runtime code, API routes, DB queries, or i18n surface changes are involved, so the localization/authorization/query-count conventions do not apply here. The global agent-browser CLI install and symlink recreation already existed; the added RUN agent-browser install and COPY --from=node-source /root/.agent-browser /root/.agent-browser are consistent with the rest of the image and keep all TLS-dependent work in the node-source stage.
The build was not run here (no shell/CI available), but the change is straightforward and the author's runtime verification in the PR description aligns with the new steps. No blocking issues found.
What does this PR do?
Bakes Chrome into the emdash-bot sandbox image at build time so the
browser-driven repro skills (
repro-admin,repro-public) can actually launcha browser.
At runtime the sandbox egress allowlist only passes GitHub/npm hosts, so
agent-browser install— which fetches Chrome for Testing from Google hosts —can never succeed inside a running container. During eval run 8 this blocked
browser verification on two cases (#1272, #1124): the agent got as far as
needing the UI and died on "Chrome install failed" SSL errors from the
intercepting proxy.
The fix follows the image's existing multi-stage pattern (all TLS work happens
in the
node-sourcestage, which has a working CA bundle): runagent-browser installthere andCOPYthe resulting/root/.agent-browsercache into the final image. The daemon auto-detects thebaked copy, so the repro skills need no changes and no runtime download is
ever attempted. The Chrome version is pinned by the image build (agent-browser
0.30.1, Chrome for Testing stable at build time — currently 151.0.7922.77).
Verified locally in the built container (linux/amd64 under Rosetta):
agent-browser doctorreports 8 pass / 0 warn / 0 fail including its liveheadless-launch test ("Headless launch + about:blank in 3.84s"), and an
open→get text→closeround-trip renders and reads a page against thebaked Chrome with no network install attempt.
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runAI-generated code disclosure
Screenshots / test output
agent-browser doctorinside the built image:open/get textround-trip:Try this PR
Open a fresh playground →
A full working EmDash site, deployed from this branch. Each visit gets its own session-scoped sandbox: no login needed and no shared state. Try the admin, edit content, hit the public site.
Tracks
bot/sandbox-baked-chrome. Updated automatically when the playground redeploys.