Skip to content
Optimal Lab

DevOps · interactive

Writing Dockerfiles that cache well

Each instruction is a cached layer. When a layer's inputs change, it and every layer after it rebuild. Copying all your code before installing dependencies means a one-line code change reinstalls everything.

  1. FROM node:22-slimCACHED
  2. WORKDIR /appCACHED
  3. COPY . .1s
  4. RUN npm ci45s
  5. RUN npm run build20s
  6. CMD ["node", "dist/server.js"]0s

rebuild: 66 s

COPY . . changed, so npm ci reruns: 45 s of reinstalling dependencies you didn't touch.

Dockerfile

You changed

Step 1 of 4

  1. 1

    Layers cache in order

    A changed layer invalidates everything after it, so order from least to most frequently changing.

    Base image, OS packages, dependencies, then code.

  2. 2

    Copy the lockfile first

    Install dependencies from package files alone, then copy the rest. Code edits skip the slow install.

    Same for pip, go mod, cargo.

  3. 3

    Multi-stage builds

    Build in a full image, then copy only the output into a slim runtime image: no compilers or dev dependencies shipped.

    FROM node:22 AS build … FROM node:22-slim

  4. 4

    .dockerignore, pinned bases, non-root user

    Keep node_modules and .git out of the context, pin image versions, and add USER node.

    In CI, cache layers between runs too.

In production

Tools and technologies

Build caching is the biggest lever on Docker build time.

Not tied to one language — use these names when you search docs or design a system.