Docker Cheatsheet
Multi-stage Builds
Use this Docker reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Why Multi-stage Builds
One Dockerfile, multiple FROM instructions. Earlier stages compile/test; only
the final stage ships. Result: production images contain no compilers, test
deps, or source code — often 10x smaller.
Basic Pattern
# Stage 1 — build FROM node:22 AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2 — production FROM node:22-alpine AS runtime WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 USER node CMD ["node", "dist/server.js"]
Copying Between Stages
# Copy a single file COPY --from=builder /app/bin/myapp /usr/local/bin/myapp # Copy a directory COPY --from=builder /app/public ./public # Copy from a public image (not just earlier stages) COPY --from=nginx:latest /etc/nginx/nginx.conf /etc/nginx/nginx.conf # Copy from an absolute stage index (0-based) COPY --from=0 /app/dist ./dist
Go Binary Example (Scratch Base)
FROM golang:1.23 AS builder WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app ./cmd/server FROM scratch COPY --from=builder /app /app COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ EXPOSE 8080 ENTRYPOINT ["/app"]
Python Example
FROM python:3.13 AS deps WORKDIR /app COPY requirements.txt . RUN pip install --prefix=/install --no-cache-dir -r requirements.txt FROM python:3.13-slim AS runtime COPY --from=deps /install /usr/local WORKDIR /app COPY . . USER nobody CMD ["python", "main.py"]
Test Stage Pattern
FROM node:22 AS deps WORKDIR /app COPY package*.json ./ RUN npm ci FROM deps AS test COPY . . RUN npm test # build fails here if tests fail FROM deps AS build COPY . . RUN npm run build FROM node:22-alpine AS runtime WORKDIR /app COPY --from=build /app/dist ./dist COPY --from=deps /app/node_modules ./node_modules CMD ["node", "dist/index.js"]
Targeting a Specific Stage
# Build only up to the "test" stage docker build --target test -t myapp:test . # Build the final (default) stage docker build -t myapp:latest . # Dev image stops at a "dev" stage that includes devDependencies docker build --target dev -t myapp:dev .
Cache Mounts in Build Stages
# syntax=docker/dockerfile:1 FROM golang:1.23 AS builder WORKDIR /src COPY . . RUN --mount=type=cache,target=/root/.cache/go-build \ --mount=type=cache,target=/go/pkg/mod \ go build -o /app .
Stage Naming Conventions
| Name | Purpose |
|---|---|
base | Shared base (OS + common tools) |
deps / vendor | Dependency install only |
builder / build | Compile / transpile |
test | Run tests (fails build if broken) |
dev | Dev tooling, hot reload |
runtime / prod | Final shipping image |
Size Comparison Cheat Sheet
| Approach | Typical size |
|---|---|
| Single-stage Node.js (node:22) | ~1.1 GB |
| Multi-stage → node:22-alpine | ~200 MB |
| Go: multi-stage → scratch | 5–15 MB |
| Python: multi-stage → slim | ~80 MB |