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%.
Top comments (0)