⚡ Docker Performance Optimization
Learn how to build smaller, faster Docker images and optimize container performance for production.
Image Size Optimization
1. Use Alpine Base Images
# Instead of
FROM node:20 # ~1GB
# Use
FROM node:20-alpine # ~150MB2. Multi-Stage Builds
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# Only copy what's needed
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]3. Layer Optimization
# Bad - cache invalidation on any change
COPY . .
RUN npm install
# Good - leverage cache
COPY package*.json ./
RUN npm ci
COPY . .4. Remove Unnecessary Files
Create .dockerignore:
node_modules
.git
.github
*.md
.env*
.vscode
coverage
tests
__tests__Build Performance
Use BuildKit
# Enable BuildKit
export DOCKER_BUILDKIT=1
# Or in Docker daemon config
{
"features": {
"buildkit": true
}
}Cache Dependencies
# Cache npm packages
RUN --mount=type=cache,target=/root/.npm \
npm ci --only=productionParallel Builds
# docker-compose.yml
services:
frontend:
build:
context: ./frontend
cache_from:
- myapp/frontend:cache
backend:
build:
context: ./backend
cache_from:
- myapp/backend:cache# Build in parallel
docker compose build --parallelRuntime Performance
1. Resource Limits
# docker-compose.yml
services:
app:
image: myapp
deploy:
resources:
limits:
cpus: "2"
memory: 512M
reservations:
cpus: "0.5"
memory: 256M2. Health Checks
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 13. Logging Configuration
services:
app:
image: myapp
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"Image Size Comparison
| Approach | Size |
|---|---|
node:20 | ~1GB |
node:20-slim | ~250MB |
node:20-alpine | ~150MB |
| Multi-stage + Alpine | ~80MB |
With .dockerignore | ~50MB |
Security Best Practices
# Run as non-root user
RUN addgroup -g 1001 -S appgroup && \
adduser -u 1001 -S appuser -G appgroup
USER appuser
# Use specific versions
FROM node:20.10.0-alpine3.18
# Scan for vulnerabilities
# docker scout cve myapp:latestQuick Optimization Checklist
- Use Alpine or distroless base images
- Implement multi-stage builds
- Create comprehensive
.dockerignore - Order layers by change frequency
- Enable BuildKit
- Set resource limits
- Configure health checks
- Run as non-root user
- Pin dependency versions
- Scan images for vulnerabilities
Commands Reference
# Check image size
docker images myapp
# Analyze layers
docker history myapp
# Inspect image
docker inspect myapp
# Prune unused images
docker image prune -a
# Build with cache
docker build --cache-from myapp:latest -t myapp:new .💡 Pro Tip: Use
divetool to analyze Docker image layers:dive myapp:latest
Published: December 10, 2024