ci: portable Rust layer cache via cargo-chef + GHA cache (JEF-87)#62
Merged
Conversation
Restructure the server image with cargo-chef so the slow dependency compile becomes its own layer keyed on the dependency recipe, and push that layer to GitHub's Actions Cache (cache-from/to type=gha,mode=max on build-push-action). Unlike the per-node BuildKit cache mounts (JEF-81), the GHA layer cache is portable: a cold runner pulls the compiled deps from GitHub instead of recompiling them. The `cook` stage holds the dep build; a thin app stage then recompiles only our crate on a source change. registry/git stay as LAN-local cache mounts, but the target mount is dropped from the dep step so its output bakes into the cacheable layer instead of an ephemeral mount. Tradeoff: mode=max ships the dep cache over the home WAN each build (caveat in JEF-87; to be measured in JEF-82). Validated locally: `cargo chef cook` from a recipe-only dir compiles all deps (build.rs/sqlx/rust-embed cooperate), and a follow-up real build recompiles only watcher-server, reusing the cooked deps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Implements JEF-87. Makes the server image's Rust dependency cache portable across nodes instead of stuck on each node's BuildKit daemon. (Reopened — supersedes #60, which auto-closed when its branch was deleted during a failed merge.)
What
server/Dockerfile→ cargo-chef. Aplannerstage distills the dep graph intorecipe.json; acookstage compiles only dependencies into its own layer keyed on that recipe; a thin final stage compiles just our crate. The dep layer cache-hits untilCargo.lockchanges.ci.yml→ GHA layer cache.cache-from: type=gha/cache-to: type=gha,mode=maxondocker/build-push-action. GitHub's Actions Cache is portable, so a cold runner pulls the compiled deps from GitHub rather than recompiling.registry/gitstay as LAN-local cache mounts; thetargetmount is dropped from the dep step so its output bakes into the cacheable layer.Tradeoff
mode=maxships the dep cache over the home WAN each build. Usually net-positive (download < recompile) — measure in JEF-82.Validation
Docker daemon wasn't available locally, so I exercised the cargo-chef path on the host:
cargo chef cookfrom a recipe-only dir compiles all deps clean (build.rs/sqlx/rust-embed cooperate); overlaying real source recompiles onlywatcher-server, reusing cooked deps.Verify in CI on merge
The
imagejob (main only) offloads to the in-cluster remote BuildKit; confirm it can reach GitHub's cache API with the injected token. Firstmainbuild seeds the cache; the second should show a cook-layer hit.🤖 Generated with Claude Code