BlogCI/CD
Dockerfile layer caching: order matters more than you think
Order your instructions so dependency layers stay cached and only your code layer rebuilds — seconds, not minutes.
Docker caches each instruction as a layer and reuses it until something upstream changes. Order your Dockerfile so the things that rarely change (dependencies) come before the thing that always changes (your source), and rebuilds go from minutes to seconds.
Cache-busting order
COPY . . first
then install deps
any code edit
-> reinstall everything
Cache-friendly order
COPY lockfile first
install deps (cached)
COPY source last
-> only code layer rebuilds
The slow version
Dockerfile (slow)
FROM node:20-slimWORKDIR /appCOPY . . # any file change busts the cache belowRUN npm ci # so this reinstalls on every commit
The fast version
Dockerfile (fast)
FROM node:20-slimWORKDIR /appCOPY package*.json ./ # changes only when deps changeRUN npm ci # cached across code-only commitsCOPY . . # your code, the volatile layer, last
docker build -t app . => CACHED [2/4] COPY package*.json ./ => CACHED [3/4] RUN npm ci => build finished in 3.1s (was 48s)Cache mounts for the package cache
With BuildKit, RUN --mount=type=cache,target=/root/.npm keeps the download cache across builds even when the layer itself rebuilds — best of both worlds.