Multi-Stage Docker Builds
Advancedv1.0.0
Master multi-stage Docker builds to create minimal production images — separate build dependencies from runtime, reduce image size by 90%, and eliminate security vulnerabilities.
Content
Overview
Multi-stage builds use multiple FROM statements in a single Dockerfile. Each stage can use a different base image, and you selectively copy artifacts from build stages into the final runtime image. This produces minimal images without build tools, compilers, or dev dependencies.
Why This Matters
- -Smaller images — production images can be 10-50x smaller than single-stage builds
- -Fewer CVEs — no build tools, compilers, or package managers in runtime image
- -Faster deployments — smaller images push/pull faster across registries
- -Better caching — Docker caches each stage independently
Step 1: Understand the Problem
Single-Stage Build (Bad)
Step 2: Convert to Multi-Stage
Multi-Stage Build (Good)
Step 3: Advanced Patterns
Separate Dependency Install from Build
Go Binary (Scratch Image)
Step 4: Use BuildKit Secrets for Private Registries
Best Practices
- -Name stages clearly:
AS builder,AS deps,AS runtime - -Use
--from=<stage>to copy only what the runtime needs - -Install prod dependencies separately from dev dependencies
- -Use distroless or scratch for the final stage when possible
- -Leverage BuildKit cache mounts:
--mount=type=cache,target=/root/.npm
Common Mistakes
- -Copying the entire
node_modulesincluding dev dependencies into the runtime image - -Not using
.dockerignore— sendingnode_modulesand.gitas build context - -Using a full OS base image (ubuntu, debian) in the runtime stage
- -Forgetting to copy SSL certificates into scratch images
FAQ
Discussion
Loading comments...