Basic

Tags, layers, and the cache

A build is a stack of layers, one per instruction, and each layer is keyed by a hash of its inputs. If the inputs of a line have not changed, the line is skipped and the cached layer is reused. That is why build order matters more than build syntax.

What you will see

Takes about four seconds. The hash changed, so the layer reruns.

About 1 min of reading

Try It

Watch the cache hit and miss

1

Write a two-line recipe

echo -e 'FROM python:3.12\nRUN sleep 3' > Dockerfile

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A Dockerfile with a base image and one slow instruction.
2

Build once

docker build -t demo:v1 .

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Takes about three seconds; the sleep runs.
3

Build again

docker build -t demo:v2 .

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Near instant. The layer is reused because the instruction text is unchanged.
4

Change the instruction

echo -e 'FROM python:3.12\nRUN sleep 4' > Dockerfile && docker build -t demo:v3 .

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Takes about four seconds. The hash changed, so the layer reruns.
Changing only the tag does not bust the cache. The cache key is the instruction, not the name you give the result.

Data Flow

Instruction to cached layer
1 Hash the instruction plus its inputs
↓
2 Look up the hash in the local store
↓
3 Hit: reuse the layer, continue
↓
4 Miss: run the instruction, store the new layer
Why this works
The cache is a correctness tool

The cache is not only a speed trick. It is a proof that a layer's inputs did not change. If you want a layer to rebuild, change its inputs; if you want it to stay cached, do not touch them.

When the cache lies

A RUN curl https://x line is cached on the command text, not on the fetched content. The fetch can be stale while the hash matches. Bust it with a build arg you pass in, or fetch at runtime.

Examples

Copy after install

COPY . . before apt install means every source edit invalidates the install layer and reinstalls everything. Put the slow, rarely-changing lines first and the fast, often-changing ones last.

One RUN per layer

Each instruction is a layer. RUN apt install x then RUN rm /tmp/y leaves x installed and y deleted in a layer that still costs space. Chain with && and clean in the same RUN.

Tag what you ship

docker build -t app:v1.4.2 . names the artifact. Without a tag you get a hash you cannot grep for later, and you cannot roll back to a named version.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Reading a version string
Previous Lesson
Reading a version string
Next Lesson
Writing a changelog people can act on
Writing a changelog people can act on →