Course outline · 0% complete

0/29 lessons0%

Course overview →

Layers: how images are really stored

lesson 3-2 · ~13 min · 8/29

Images are stacks of layers

How images are stored sounds like trivia, and it decides two things you feel every day: how long docker build takes, covered next lesson, and how long every push, pull, and deploy takes, covered in unit 6.

An image is not one big blob. Each instruction in the Dockerfile from lesson 3-1 produces a layer, a read-only diff containing only what that instruction changed.

InstructionLayer contains
FROM python:3.12-slimthe base layers, OS files and Python
COPY requirements.txt .one small file
RUN pip install ...the installed packages
COPY . .your source code

The final image is this stack read together. When a container runs, Docker puts the thin writable layer from lesson 1-2 on top, and everything below stays read-only forever.

The payoff is sharing. If ten of your images all start FROM python:3.12-slim, those base layers exist once on disk and are downloaded once, and only each image's small unique layers differ.

each Dockerfile instruction adds a read-only layerFROM python:3.12-slim · base OS + PythonCOPY requirements.txt . · one small fileRUN pip install ... · installed packagesCOPY . . · your source codecontainer's writable layer (only at run time)
An image builds up as a stack of read-only layers, one per instruction. At run time a container adds a single writable layer on top, the same one you met in lesson 1-2.

Seeing the layers with docker history

The stack is not hidden, and one command prints it:

docker history myapp:v1
IMAGE          CREATED BY                                SIZE
8f3c2a91d0e4   CMD ["python" "server.py"]                0B
2b1a99c47f21   COPY . .                                  1.2MB
91c04d55ab02   RUN pip install -r requirements.txt      89MB
77e5301bfa6c   COPY requirements.txt .                   412B
...            FROM python:3.12-slim                     150MB

One row per instruction, newest on top, with the size each layer added.

Engineers reach for this when an image is mysteriously huge, because the SIZE column points straight at the guilty instruction. Here the pip install layer costs 89 MB, which is normal, while a 900 MB COPY . . row would mean junk files are being copied in.

Note also that CMD costs 0 B, which confirms it is metadata rather than content. The .dockerignore file in the next lesson is the fix for a bloated copy layer.

How often a shared base layer is stored

Ten images that all start FROM python:3.12-slim store those base layers once.

Layers are stored and downloaded once, then shared by every image and container that references them. Docker identifies each layer by a hash of its content, so an identical layer is recognized as the same object no matter which image pulled it in.

SetupDisk cost
ten full copiesten times the base
ten images sharing a baseone base plus ten thin app layers

This sharing is the reason images are practical at all. It is also why choosing the same base image across a fleet of services is a real optimization rather than a style preference.

Diagnosing an 850 MB copy layer

When docker history shows an 850 MB COPY . . layer against 2 MB of source code, the build context almost certainly contained huge extra files that the copy pulled in.

A layer contains exactly what its instruction added, so an 850 MB copy layer means 850 MB of files were copied from the build context.

Usual culpritTypical size
.git historytens to hundreds of MB
node_modules or a virtualenvhundreds of MB
data files and logsanything

The layer size is trustworthy evidence, which makes this an unusually easy diagnosis. The .dockerignore file in the next lesson excludes those paths from the context so the copy never sees them.

A layer. Every instruction produces one, the image is the ordered stack of them, and they are shared across images to save disk and download time. Layers also power the build cache, which is the next lesson.