Introduction#
After years of working with Docker in production, I’ve accumulated a set of best practices that I wish someone had told me on day one. These tips will help you build smaller, faster, and more secure containers.
1. Use Multi-Stage Builds#
One of the most impactful optimizations. Multi-stage builds let you separate your build environment from your runtime environment:
# Build stage
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server
# Runtime stage
FROM alpine:3.19
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]Result: image size drops from ~800MB to ~15MB.
2. Order Your Layers Wisely#
Docker caches layers from top to bottom. Put things that change least frequently first:
FROM node:20-alpine
WORKDIR /app
# Dependencies change less often than source code
COPY package.json package-lock.json ./
RUN npm ci --production
# Source code changes frequently
COPY . .
CMD ["node", "server.js"]3. Don’t Run as Root#
Always create a non-root user in your containers:
FROM node:20-alpine
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
USER appuser
CMD ["node", "server.js"]4. Use .dockerignore#
Just like .gitignore, a .dockerignore file prevents unnecessary files from being copied into your image:
node_modules
.git
.env
*.md
docker-compose*.yml
.github5. Pin Your Base Image Versions#
Never use latest in production. Always pin to a specific version:
# Bad
FROM node:latest
# Good
FROM node:20.11-alpine3.196. Health Checks#
Add health checks so orchestrators know when your container is truly ready:
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:8080/health || exit 1Conclusion#
These practices might seem small individually, but together they make a massive difference in production. Your containers will be smaller, build faster, start quicker, and be more secure.
Start applying these one at a time to your existing projects — you’ll see the benefits immediately.
