3.1.2.4 Image Layer Invalidation
A focused guide to Image Layer Invalidation, connecting core concepts with practical Docker and container operations.
Image layer invalidation is what happens when a change to a Dockerfile instruction, or to the files it operates on, makes a previously cached layer no longer valid to reuse — forcing that layer, and every layer after it, to be rebuilt from scratch.
Invalidation Cascades Forward
Because each layer's build context includes the state produced by every layer before it, invalidating one layer necessarily invalidates every layer that comes after it in the Dockerfile, even if those later instructions themselves did not change.
FROM node:20-alpine
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["node", "dist/server.js"]
If package*.json changes, both npm install and every instruction after it must be rebuilt, even though npm run build and the final CMD instruction did not themselves change.
What Triggers Invalidation for COPY and ADD
For COPY and ADD instructions, the cache check examines the content of the files being copied, not just the instruction's text — a file with identical content but a different modification time generally does not invalidate the cache, since the check is based on content, not metadata.
touch app.py
docker build -t myapp:1.0 .
If app.py's content is unchanged, merely updating its modification time typically does not invalidate the layer that copies it.
What Triggers Invalidation for RUN
For RUN instructions, the cache check is based on the instruction's text itself — any change to the command, even one that would produce an identical result, invalidates the cache for that layer.
RUN apt-get update && apt-get install -y curl
RUN apt-get update && apt-get install -y curl wget
Even though the first command is a subset of the second, changing from one to the other invalidates the layer entirely, since the cache comparison is textual, not semantic.
Why Understanding Invalidation Matters
Knowing exactly what triggers invalidation, and that it cascades forward through the rest of the Dockerfile, is essential for structuring a Dockerfile to minimize unnecessary rebuilding — placing the instructions most likely to change as late as possible in the file limits how much invalidation any single change actually causes.