Image Layers & Caching

Each Dockerfile instruction creates a cached layer, and understanding layers helps you build faster, smaller images.

Docker images are built in layers. Every instruction in your Dockerfile creates a new read-only layer stacked on top of the previous ones.

Why layers matter

  • Caching — if a layer has not changed, Docker reuses the cached version instead of rebuilding it, making builds much faster.
  • Sharing — images that share base layers only store them once on disk.
Stacked read-only image layers with a writable container layer on topFROM node:20-alpineCOPY package.jsonRUN npm installCOPY . .Writable container layer(added when running)read-onlylayers
Read-only layers stack from the base image upward; the container adds a thin writable layer on top.

Ordering for cache hits

Copy files that rarely change (like package.json) and install dependencies before copying your full source code. That way, editing a source file does not bust the dependency-install cache.

Example

Example · dockerfile
# Fewer, cleaner layers: install and clean up in one RUN
FROM debian:12-slim
RUN apt-get update \
 && apt-get install -y --no-install-recommends curl ca-certificates \
 && rm -rf /var/lib/apt/lists/*

When to use it

  • A developer reorders Dockerfile instructions to put rarely changed steps first, so code changes don't invalidate the dependency layer cache.
  • A build engineer notices a 2 GB image and uses docker history to identify which layer added an unexpectedly large file.
  • A CI team leverages layer caching to keep package install steps from re-running on every build, cutting build time from 4 minutes to 30 seconds.

More examples

Inspect image layer history

Lists every layer in the image with its size, creation time, and the Dockerfile instruction that created it.

Example · bash
docker image history myapp:1.0

# Show full command for each layer
docker image history --no-trunc myapp:1.0

Dockerfile with cache-friendly order

Puts slow, rarely-changing steps (npm install) before frequently-changing steps (source copy) to maximise cache hits.

Example · dockerfile
FROM node:20-alpine
WORKDIR /app
# Copy dependencies first — only re-runs when package.json changes
COPY package*.json ./
RUN npm ci
# Copy source last — changes here don't bust the npm layer
COPY . .

Collapse RUN commands to merge layers

Chains commands with && so the cache cleanup happens in the same layer as the install, preventing extra disk usage.

Example · dockerfile
# Bad: creates 3 layers
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*

# Good: one layer, smaller image
RUN apt-get update \
 && apt-get install -y curl \
 && rm -rf /var/lib/apt/lists/*

Discussion

  • Be the first to comment on this lesson.