Dockerfile Best Practices
Write efficient Dockerfiles with best practices: layer ordering, caching, .dockerignore, non-root users, health checks, and security hardening.
Build
Detailed Explanation
Dockerfile Best Practices
1. Use Specific Base Image Tags
# BAD: unpredictable
FROM node:latest
# GOOD: pinned version
FROM node:20.11-alpine3.19
2. Order Layers by Change Frequency
Put rarely-changing instructions first to maximize cache hits:
FROM node:20-alpine
WORKDIR /app
# These change rarely - cached
COPY package.json package-lock.json ./
RUN npm ci --production
# This changes often - rebuilds from here
COPY . .
3. Minimize Layer Count
Combine related commands in a single RUN:
# BAD: 3 layers
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
# GOOD: 1 layer
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
4. Use .dockerignore
node_modules
.git
.env
*.md
dist
.DS_Store
5. Run as Non-Root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
6. Add Health Checks
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
7. Use COPY Instead of ADD
# Prefer COPY for simple file copying
COPY ./config /app/config
# Use ADD only for tar extraction
ADD archive.tar.gz /opt/
8. Set Appropriate Labels
LABEL org.opencontainers.image.source="https://github.com/org/repo"
LABEL org.opencontainers.image.version="1.0.0"
LABEL org.opencontainers.image.description="My application"
Use Case
Writing production-grade Dockerfiles that build faster, produce smaller images, follow security best practices, and are maintainable by teams.