iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Layers & Caching

Each instruction in a Dockerfile creates a layer. The build cache reuses a layer when its instruction and the files it depends on are unchanged, so layer ordering is the single biggest lever you have over rebuild time and image size. The rule: put slow, rarely-changing steps before fast, often-changing ones.

A layer-aware Dockerfile for a Node app

EXAMPLE
# syntax=docker/dockerfile:1.7
ARG NODE_VERSION=20

# ---------- deps stage: only invalidated when lockfile changes ----------
FROM node:${NODE_VERSION}-alpine AS deps
WORKDIR /app
# Copy only manifests first so 'npm ci' is cached unless lockfile moves
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \
    npm ci --omit=dev

# ---------- build stage: source code changes invalidate from here down ---
FROM node:${NODE_VERSION}-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY tsconfig.json ./
COPY src ./src
RUN npm run build

# ---------- runtime: tiny final image, no build tools ----------
FROM node:${NODE_VERSION}-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps  /app/node_modules ./node_modules
COPY --from=build /app/dist         ./dist
COPY package.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

# Build:  docker build -t app:dev .
# Inspect layer sizes:   docker history app:dev
# Inspect contents:      docker run --rm -it app:dev sh

Why it matters

Multi-stage builds keep your final image free of compilers, dev dependencies, and source code. Pair them with a BuildKit cache mount (--mount=type=cache) and a .dockerignore that excludes node_modules and .git, and warm rebuilds drop from minutes to seconds.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Each line in a Dockerfile = a cacheable layer.
# Order matters: copy package.json BEFORE source, so npm install caches.
Try it Yourself »

Discussion

Loading…