Optimizing Docker images is crucial for faster builds, reduced attack surface, and efficient deployments. In production, a bloated image can slow down CI/CD pipelines and increase security risks. Here are some best practices to help you create lean, secure, and performant Docker images.
1. Use Official and Minimal Base Images
Start with official images from Docker Hub and prefer minimal distributions like alpine
when possible. For example, node:18-alpine
is much smaller than node:18
.
2. Multi-Stage Builds
Multi-stage builds allow you to separate build dependencies from runtime, resulting in smaller final images. Here’s an example for a Node.js app:
# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
3. Minimize Layers and Remove Unnecessary Files
Each RUN
, COPY
, or ADD
creates a new layer. Combine commands where possible and remove files you don’t need in production (like docs, tests, or build caches).
RUN npm ci --only=production \
&& npm cache clean --force \
&& rm -rf /tmp/*
4. Use .dockerignore
Just like .gitignore
, a .dockerignore
file prevents unnecessary files (like node_modules
, logs, or local configs) from being copied into the image, reducing build context size and improving build speed.
node_modules
npm-debug.log
Dockerfile*
.dockerignore
.git
.gitignore
tests
*.md
5. Pin Dependencies and Versions
Always pin your base image and package versions to avoid unexpected changes and ensure reproducible builds. For example: FROM node:18.17.0-alpine
.
6. Security Best Practices
- Run as a non-root user in production images.
- Scan images for vulnerabilities using tools like
docker scan
ortrivy
. - Keep images up to date with security patches.
- Minimize installed packages to reduce attack surface.
Conclusion
By following these practices, you’ll create Docker images that are smaller, faster, and more secure—leading to better performance and safer deployments in production environments.