Why Your Docker Container Is 1.2GB When It Should Be 80MB
18 hours ago
- #docker
- #optimization
- #security
- Using the wrong base image, like 'node:20' instead of 'node:20-alpine', causes significant bloat (e.g., 1.1GB vs. 56MB base).
- Installing development dependencies in production images, such as Jest or TypeScript, unnecessarily increases size; use 'npm ci --only=production' or multi-stage builds to separate dev tools.
- Missing a .dockerignore file leads to large build contexts by including unnecessary files like node_modules, .git, and logs, slowing builds and increasing image size.
- Creating too many RUN layers in a Dockerfile can bloat the image because deletions in subsequent layers don't remove data from earlier layers; combine commands into single RUN instructions.
- Running containers as root and installing unnecessary tools (e.g., curl, git) increases attack surface; switch to a non-root user and remove unneeded packages for security.
- A full optimized Dockerfile for a TypeScript Node.js API with multi-stage builds, Alpine base, production-only dependencies, proper .dockerignore, combined RUN layers, and non-root user reduced image size from 1.24GB to 78MB (94% reduction).
- Smaller images (e.g., 80MB) improve pull times, registry storage costs, security (fewer CVEs), and developer experience, making production environments cleaner and more efficient.
- Regularly scan images with tools like Docker Scout or Trivy to identify vulnerabilities, especially after optimizations, and ensure security compliance in CI/CD pipelines.