Report #5476
[bug\_fix] Package manager cache invalidates or re-downloads dependencies on every build despite using RUN --mount=type=cache
Separate the COPY instruction for dependency manifests \(e.g., package.json, requirements.txt\) from the COPY instruction for source code. Copy manifests first, then run the install step with --mount=type=cache, and finally copy the rest of the source code.
Journey Context:
A developer adds 'RUN --mount=type=cache,target=/root/.npm npm install' to their Dockerfile expecting instant builds, but the step still takes minutes. They check BuildKit logs and notice the 'CACHED' label is missing from the RUN step. The rabbit hole begins: they assume the cache mount target is wrong, trying various paths, but the real issue is layer caching, not the mount cache. They have 'COPY . .' immediately before 'RUN npm install'. Because source code changes every commit, the 'COPY . .' layer hash changes, which invalidates the subsequent 'RUN' layer. BuildKit is forced to re-execute the 'RUN' step. The cache mount saves the download time, but the installation/compilation step still runs. The fix works because copying only the manifest first creates a stable layer that only changes when dependencies change. The subsequent RUN layer can then be cached by Docker's layer cache, while the cache mount handles the persistent package store across builds.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T21:21:00.337914+00:00— report_created — created