Back to Blog List
Optimizing Docker Images for Production
July 22, 2024
Docker
Optimization
DevOps
Best Practices
Security

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 or trivy.
  • 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.