Repository navigation
perf(claude-code): install Claude Code last and cache CI layers - #183
Merged
Merged
Conversation
- Move the Claude Code npm install to the end of the default and sandbox targets; keep the version as one global ARG for Renovate - Re-declare the ARG only directly above the install: an ARG joins the cache key of every later RUN, which rebuilt Chromium per bump - Enable the GHA layer cache for both build jobs, with explicit scopes - Verified locally: a version-only bump changes 1 of 23 layers (default) and 1 of 22 (sandbox)
…yer-cache # Conflicts: # claude-code/.devcontainer/Dockerfile
This was referenced Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Make a Claude Code version bump republish only the Claude Code layer of
claude-code/claude-code-sandbox, instead of most of the image.Why
Renovate bumps
@anthropic-ai/claude-codeseveral times a week (five merges in the week before this PR), and each bump currently republishes almost the whole image:build-claude-code.ymlnever enabled the build cache (docker/github-builderdefaults tocache: false), so every CI run rebuilds every layer from scratch with new digests.ARG CLAUDE_CODE_VERSIONwas declared inbase. An ARG becomes part of the cache key of every laterRUN, including in stages builtFROM base. The published history confirms it: the Chromium step was recorded asRUN |2 GH_VERSION=… CLAUDE_CODE_VERSION=… apt-get install chromium …. So even with caching on, every bump would have rebuilt Chromium (267 MB compressed) and agent-browser (101 MB).Changes
ARG CLAUDE_CODE_VERSION=…now sits at the top of the file. Renovate still has exactly one line to bump; I checked its regex against the new file.npm installout ofbase. It is now the last build step in bothdefaultandsandbox, each preceded by a bareARG CLAUDE_CODE_VERSION.cache: truewith explicitcache-scopes (claude-code,claude-code-sandbox). The default scope would be the bare target namedefault.cache-modestays at its default,min, because every heavy layer is in the final stage.Testing
Built each target twice locally (arm64), changing only
CLAUDE_CODE_VERSION(2.1.284 → 2.1.285), and comparedRootFS.Layers:defaultnpm install -g @anthropic-ai/claude-codesandboxnpm install -g @anthropic-ai/claude-codehadolint-action@v3.0.0pins) and actionlint pass.Notes
apt-get install chromiumlayer now refreshes only when something below it changes, such as a newnode:24-trixie-slimdigest or a bump to gh / gh-stack / rtk / ralphex / mise. Before this change it reinstalled on every build. Expect Debian Chromium security updates to lag by up to about a week. This fits the image's "rebuild on releases, not on a schedule" policy.base(gh, gh-stack, rtk, ralphex) still invalidates everything above it, including Chromium. That's less frequent and out of scope here, as is ralphex-fe.