Why Your Docker Builds Are Slow (And How to Cut Them by 90%)
Nothing kills developer momentum quite like waiting 14 minutes for a CI Docker build to finish after modifying a single CSS variable or fixing a typo.
In this guide, we'll examine:
- The Law of Downstream Cache Invalidation
- The Golden Order of Dockerfile Instructions
- Multi-Stage Builds: Slicing 1.8GB down to 48MB
- BuildKit
--mount=type=cachefor Instant Package Installs - Interactive Practice with "Docker Build Speed Run"
1. The Classic 14-Minute Bloat Monster
Look at this typical Dockerfile:
FROM node:latest WORKDIR /app COPY . . RUN npm install RUN npm run build EXPOSE 3000 CMD ["npm", "start"] What went wrong?
COPY . . sits on line 3, before RUN npm install.
Because Docker computes a cryptographic checksum of all files in the build context during COPY, any minor code commit invalidates this layer. Downstream, Docker discards the npm install cache and re-downloads all packages over the network.
2. The 3 Steps to Sub-Second Builds
Step 1: Isolate Dependency Manifests
COPY package*.json ./ RUN npm ci --only=production COPY . . Step 2: Multi-Stage Distillation
# Builder Stage FROM node:20-alpine AS builder WORKDIR /build COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Lean Production Runner FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY --from=builder /build/package*.json ./ COPY --from=builder /build/node_modules ./node_modules COPY --from=builder /build/dist ./dist USER node CMD ["node", "dist/server.js"] Step 3: BuildKit Cache Mounts
# syntax=docker/dockerfile:1.4 RUN --mount=type=cache,target=/root/.npm npm ci 3. Practice Live in Your Browser: Docker Build Speed Run
I built an interactive educational arcade game where you can drag, swap, and optimize 8 real-world Dockerfile disasters:
🎮 Play Docker Build Speed Run: https://games.naveedkumbhar.com/docker/
Features:
- Live Simulated Build Time & Image Size HUD
- Cache Hit Efficiency Gauge
- 8 Enterprise Stacks: Node.js, Python FastAPI, Go Distroless, Spring Boot, Rust Cargo-Chef, Next.js Standalone, Rootless Debian, and Monorepo Turborepo
- 100% mobile touch friendly (tap-to-swap & nudge buttons)
Read the full production engineering guide: How to Cut Docker Build Times by 90%.
