Docker Layer Cache & Multi-Stage Build Lab (Interactive)
Reorder Dockerfile instructions to keep the dependency layer cached and shrink images from 410 MB to distroless 20 MB. Compare naive, cache-ordered and multi-stage builds on CI minutes, image size and CVE count as you change source versus dependencies.
Docker Layer Cache & Multi-Stage Build Lab
One cache miss invalidates every subsequent layer. Reorder instructions, split stages, and price the build in CI minutes and CVEs.
Image layer stack — simulating: a source edit
Source-edit / dep build
2s / 98s
Monthly CI minutes
750
Final image / pull
190 MB · 4.8s
Open CVEs · shell
41 · /bin/sh yes
Manifest-first ordering keeps npm ci cached across source edits: only the 2s COPY src layer (plus cascade) rebuilds. --omit=dev drops dev tooling, and USER node runs the process unprivileged.
How It Works Under the Hood
An OCI image is a stack of immutable, hash-addressed OverlayFS layers, and Docker rebuilds a layer only when it or any ancestor changes. Copying your whole source before installing dependencies means every one-character edit invalidates the 95-second npm/go layer, so the cache never fires. Copy the manifest first, install dependencies, then copy source, and normal code edits rebuild only a two-second layer. Multi-stage builds take it further: a heavy compiler stage produces a static binary that the only artifact copied into a distroless runtime, cutting pull time and stripping the shell that attackers need.
Core Architectural Principles
- A cache miss on any layer invalidates every subsequent layer, so order least-to-most frequently changed.
- Multi-stage COPY --from discards the entire builder toolchain, shipping only the compiled binary.
- Distroless images have no /bin/sh or package manager, collapsing the CVE surface and blocking reverse shells.
When discussing containerization, lead with layer cache invalidation: explain why COPY package.json before RUN npm ci before COPY src keeps dep downloads cached across code edits. Then propose multi-stage builds with a distroless nonroot final stage to cut image pull time during Kubernetes scale-out and shrink CVEs. Mentioning read-only root filesystem and dropped capabilities signals production hardening experience.
Cache-ordered multi-stage Dockerfiles build seconds-not-minutes images with minimal CVEs, at the cost of harder authoring and loss of in-container shell debugging.