Goal
Prevent the cargo chef cook (dependency) layers from being invalidated on every source code change by replacing the full-tree COPY . /build/src in the recipe stage with a manifest-only copy of Cargo.toml and Cargo.lock files.
Background
The current recipe stage does:
FROM chef AS recipe
WORKDIR /build/src
COPY . /build/src # copies the entire source tree
RUN cargo chef prepare --recipe-path /build/recipe.json
The cargo chef prepare command only reads Cargo.toml manifests and Cargo.lock to build recipe.json. It does not read any .rs source files. This is explicitly stated in cargo-chef's own CLI description:
"Analyze the current project to determine the minimum subset of files (Cargo.lock and Cargo.toml manifests) required to build it and cache dependencies"
Because COPY . /build/src copies all source files into the recipe stage, Docker invalidates that layer's cache whenever any tracked file changes — including .rs files, documentation, and scripts. Since the recipe stage is upstream of both dependencies and dependencies_debug cook stages, this cascades into a full external dependency recompile (~200–400 s) on every PR that only changes application code.
The Fix
Replace the full-tree copy with a manifest-only copy in the recipe stage — one COPY line per workspace member Cargo.toml, plus the root Cargo.lock. After this change, the recipe stage cache (and therefore the cook layers) is only invalidated when Cargo.toml or Cargo.lock actually changes — not on every .rs edit.
Maintenance Cost
The manifest-only COPY list must be kept in sync with the workspace member list in the root Cargo.toml. The workspace is relatively stable (packages are being extracted to separate repos under EPIC #1669, reducing the list over time). A CI check can catch drift automatically.
Acceptance Criteria
Related
Goal
Prevent the
cargo chef cook(dependency) layers from being invalidated on every source code change by replacing the full-treeCOPY . /build/srcin therecipestage with a manifest-only copy ofCargo.tomlandCargo.lockfiles.Background
The current
recipestage does:The
cargo chef preparecommand only readsCargo.tomlmanifests andCargo.lockto buildrecipe.json. It does not read any.rssource files. This is explicitly stated incargo-chef's own CLI description:Because
COPY . /build/srccopies all source files into the recipe stage, Docker invalidates that layer's cache whenever any tracked file changes — including.rsfiles, documentation, and scripts. Since the recipe stage is upstream of bothdependenciesanddependencies_debugcook stages, this cascades into a full external dependency recompile (~200–400 s) on every PR that only changes application code.The Fix
Replace the full-tree copy with a manifest-only copy in the recipe stage — one
COPYline per workspace memberCargo.toml, plus the rootCargo.lock. After this change, the recipe stage cache (and therefore the cook layers) is only invalidated whenCargo.tomlorCargo.lockactually changes — not on every.rsedit.Maintenance Cost
The manifest-only COPY list must be kept in sync with the workspace member list in the root
Cargo.toml. The workspace is relatively stable (packages are being extracted to separate repos under EPIC #1669, reducing the list over time). A CI check can catch drift automatically.Acceptance Criteria
recipestage uses only manifest-only COPY lines — noCOPY . /build/src.cargo chef prepareproduces arecipe.jsonequivalent to the current output..rs-only change no longer invalidates the cook layers..rs-only changes is measured and documented.Related
docs/issues/open/(after spec PR merge)