perf: prebuild the agent image and unify tool installation - #4
perf: prebuild the agent image and unify tool installation#4akalipetis wants to merge 4 commits into
Conversation
Tool installation ran inline in `setup.install` on every sandbox creation: the Pi installer plus two npm installs plus a Webi fetch, roughly 60-90s each time. It now lives in one place, `files/home/.lambda/install-tools.sh`, with two consumers: the Dockerfile bakes it into cached layers, and `setup.install` runs the same script so the kit still works on a plain shell-docker base. Static files under `files/home/` land before install commands, which is what makes sharing possible. Every step stays guarded and idempotent, so the script no-ops against an image that already has the tools. `setup.install` drops from ten commands to six, and every remaining one depends on runtime state: volume-mount ownership, npm proxy configuration, and config seeding that reads WORKSPACE_DIR. `sandbox.image` points at ghcr.io/withlogicco/sbx-kit-lambda:latest, built by .github/workflows/image.yml for linux/amd64 and linux/arm64 on pushes to main, on tags, weekly, and on manual dispatch. The image is public, so no registry credential is needed, and the workflow asserts the agent-image contract and every expected binary against the pushed digest. Until CI publishes the tag the `lambda` shell helper builds it locally under the same name, so no spec change is needed when CI takes over. `sandbox.build` is declared alongside `image` so the image's origin is discoverable from the spec. sbx does not act on it and emits one notice saying the image is taken from sandbox.image; that notice is expected. Declaring `build` without `image` is not an option — the kit fails validation outright. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f3793cd768
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| push: true | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| labels: ${{ steps.meta.outputs.labels }} | ||
| cache-from: type=gha |
There was a problem hiding this comment.
Bust the install cache during weekly refreshes
On scheduled runs where the Dockerfile, installer, and base-image digest are unchanged, this GHA cache allows BuildKit to reuse the existing RUN sh /tmp/install-tools.sh layer; remote Pi/npm/Webi releases are not cache-key inputs. The weekly workflow therefore republishes the same tool versions instead of performing its stated refresh, potentially leaving the image stale indefinitely. Disable caching for the installation stage or add a schedule-specific cache-busting input.
Useful? React with 👍 / 👎.
| paths: | ||
| - Dockerfile | ||
| - .github/workflows/image.yml |
There was a problem hiding this comment.
Trigger image builds when the installer changes
When files/home/.lambda/install-tools.sh changes on main, this path filter skips the image workflow because it lists only the Dockerfile and workflow. New sandboxes consequently keep receiving the old baked tools and installation behavior until a scheduled or manual build runs; add the shared installer (and other effective build-context inputs) to this filter.
AGENTS.md reference: AGENTS.md:L25-L29
Useful? React with 👍 / 👎.
Stacked on #2, which is stacked on #1 — merge in order. Base is
feature-agent-kit, so this PR's diff is only the image work.Why
Tool installation ran inline in
setup.installon every sandbox creation: the Pi installer, two npm installs, and a Webi fetch — roughly 60–90s each time.The main change: one script, two consumers
Rather than duplicating installs between a Dockerfile and
setup.install, tool installation now lives in exactly one place —files/home/.lambda/install-tools.sh:COPYs and runs it, baking the tools into cached layerssetup.installruns the same script, so the kit still works on a plainshell-dockerbase or if an image pull failsStatic files under
files/home/land before install commands, which is what makes sharing possible. Every step iscommand -vguarded and idempotent, so the script no-ops against an image that already has the tools.setup.installdrops from 10 commands to 6, and every survivor needs runtime state an image cannot have:chown$HTTP_PROXYinstall-tools.shconfig.toml~/.claude.json$WORKSPACE_DIRsettings.jsonImage publishing
.github/workflows/image.ymlbuildslinux/amd64+linux/arm64and pushes toghcr.io/withlogicco/sbx-kit-lambdaon pushes tomain, on tags, weekly (tool versions float), and onworkflow_dispatch. Public, so no registry credential. The workflow asserts the agent-image contract against the pushed digest —agentis UID 1000, all four binaries resolve, andlambdareally points atpi.On
sandbox.buildIt's declared alongside
imageso the image's origin is discoverable from the spec, but it buys no behavior. sbx accepts it and warns:That notice on every
validate/inspectis expected, not a regression. Declaringbuildwithoutimageis not an option — the kit fails validation outright:Worth revisiting if sbx ever implements it: for a kit consumed over
git+https://, honouringbuildwould switch every user from pulling a cached multi-arch image to building locally on first create. Pulling from GHCR is the better end state, not a stopgap.Two things to know before merging
sandbox.imagenames a GHCR tag that doesn't exist yet. The intent is that a localdocker build -t ghcr.io/withlogicco/sbx-kit-lambda:latest .satisfies it, so nothing changes when CI takes over — and thelambdashell helper builds on demand, with--buildto force a rebuild. This could not be tested: the Docker daemon was down. If sbx always pulls, pointimageback atdocker/sandbox-templates:shell-dockeruntil CI publishes; the guarded script makes that a one-line change.The image has never been built. Same reason. The workflow's contract check is its first real test, so expect to iterate on the Dockerfile if that step fails.
Also note a local build masquerades as the published tag, so
docker image inspectis the only way to tell whether you're on a local build or the real one.🤖 Generated with Claude Code