Multi-Stage Docker Builds
Learn how to create efficient, production-ready Docker images using multi-stage builds
Quick Navigation
Difficulty: 🟡 Intermediate
Estimated Time: 20-30 minutes
Prerequisites: Basic Docker knowledge, Understanding of Dockerfile syntax, Command line experience
What You'll Learn
This tutorial covers essential multi-stage build concepts and tools:
- Multi-stage build concepts - Understanding the benefits and use cases
- Build optimization - Reducing final image size significantly
- Security improvements - Excluding build tools from production images
- Practical examples - Real-world applications for different languages
- Advanced techniques - Build arguments and multi-platform builds
Prerequisites
- Basic Docker knowledge
- Understanding of Dockerfile syntax
- Command line experience
Related Tutorials
- Docker Compose for Development - Development workflow setup
- Optimizing Docker Images - Advanced image optimization
- Docker Best Practices 2025 - Production strategies
Introduction
Multi-stage builds are a powerful Docker feature that allows you to use multiple FROM
statements in your Dockerfile. Each FROM
statement starts a new stage of the build, and you can selectively copy artifacts from one stage to another. This results in smaller, more secure production images.
Why Use Multi-Stage Builds?
- Smaller images - Exclude build tools and dependencies
- Better security - Remove unnecessary packages and tools
- Cleaner separation - Build environment vs. runtime environment
- Easier maintenance - Single Dockerfile for entire build process
Step-by-Step Instructions
Step 1: Basic Multi-Stage Structure
Create a new directory and Dockerfile:
mkdir multi-stage-demo
cd multi-stage-demo
touch Dockerfile
Step 2: Create a Simple Multi-Stage Dockerfile
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy source code
COPY . .
# Build the application
RUN npm run build
# Production stage
FROM nginx:alpine
# Copy built files from builder stage
COPY /app/dist /usr/share/nginx/html
# Expose port
EXPOSE 80
# Start nginx
CMD ["nginx", "-g", "daemon off;"]
Step 3: Build and Test
# Build the image
docker build -t multi-stage-demo .
# Check image size
docker images multi-stage-demo
# Run the container
docker run -p 8080:80 multi-stage-demo
Step 4: Advanced Multi-Stage Example (Go Application)
# Build stage
FROM golang:1.21-alpine AS builder
# Install git and ca-certificates
RUN apk add --no-cache git ca-certificates
WORKDIR /go/src/app
# Copy go mod files
COPY go.mod go.sum ./
# Download dependencies
RUN go mod download
# Copy source code
COPY . .
# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# Production stage
FROM scratch
# Copy ca-certificates from builder
COPY /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Copy binary from builder
COPY /go/src/app/main /app/
EXPOSE 8080
CMD ["/app/main"]
Step 5: Python Multi-Stage Example
# Build stage
FROM python:3.11-slim AS builder
WORKDIR /app
# Install build dependencies
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Copy requirements
COPY requirements.txt .
# Install Python dependencies
RUN pip install --user -r requirements.txt
# Production stage
FROM python:3.11-slim
WORKDIR /app
# Copy Python packages from builder
COPY /root/.local /root/.local
# Copy application code
COPY . .
# Make sure scripts in .local are usable
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8000
CMD ["python", "app.py"]
Advanced Techniques
Using Build Arguments
# Build stage
FROM node:18-alpine AS builder
ARG NODE_ENV=production
ARG BUILD_VERSION=1.0.0
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Production stage
FROM nginx:alpine
ARG BUILD_VERSION
LABEL version=$BUILD_VERSION
COPY /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Multi-Platform Builds
# Build stage
FROM node:18-alpine AS builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
ARG TARGETOS
ARG TARGETARCH
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Production stage
FROM nginx:alpine
COPY /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Performance Comparison
Build Type | Image Size | Build Time | Security |
---|---|---|---|
Single-stage | 850MB | 2:30 | Medium |
Multi-stage | 120MB | 3:15 | High |
Scratch-based | 15MB | 4:00 | Very High |
Troubleshooting
Common Issues and Solutions
Issue: Build stage artifacts not found
# Solution: Ensure correct stage name and path
COPY --from=builder /app/dist /usr/share/nginx/html
Issue: Large final image size
# Solution: Use .dockerignore and clean up in each stage
RUN rm -rf /var/cache/apk/* /tmp/*
Issue: Build context too large
# Solution: Create .dockerignore file
node_modules
.git
*.log
dist
Debugging Multi-Stage Builds
# Build specific stage
docker build --target builder -t debug-image .
# Run build stage for debugging
docker run -it debug-image /bin/sh
# Check intermediate layers
docker build --progress=plain .
Best Practices
Stage Naming
- Use descriptive names:
builder
,tester
,production
- Avoid generic names like
stage1
,stage2
Dependency Management
- Install only necessary packages in each stage
- Use multi-stage to separate dev and prod dependencies
Security Considerations
- Use minimal base images for production
- Remove build tools and sensitive files
- Scan final images for vulnerabilities
Optimization Tips
- Order Dockerfile instructions from least to most frequently changing
- Use
.dockerignore
to reduce build context - Leverage Docker layer caching
Conclusion
Multi-stage builds are essential for creating production-ready Docker images. They help you:
- Reduce image size significantly
- Improve security by excluding build tools
- Maintain a single Dockerfile for your entire build process
- Optimize for different environments (dev, test, prod)
Start implementing multi-stage builds in your projects today and experience the benefits of smaller, more secure Docker images!
Tags: #Docker #MultiStage #Builds #Optimization #Production #Efficiency