Optimizing Container Images: From 1.2 GB to 45 MB
Large Docker images slow down CI/CD pipelines and deployments. With multi-stage builds and best practices, you can drastically reduce image size.
Why Image Size Matters
A 1.2 GB Docker image means: slower builds, slower pushes to the registry, slower pulls on the nodes, and a larger attack surface. Smaller images are faster and more secure.
Multi-Stage Builds
The most important lever: separate build dependencies from runtime dependencies. In the build stage, install compilers, build tools, and dev dependencies. Into the final stage, copy only the compiled artifacts.
Base Image Selection
- Alpine: ~5 MB base image, ideal for Go and Rust applications. Caution with PHP and Python — musl vs. glibc can cause compatibility issues.
- Distroless: Google's Distroless images contain only the runtime — no shell, no package managers. Maximum security.
- Debian Slim: A good compromise between compatibility and size for PHP and Node.js applications.
Layer Optimization
- Order: Rarely changing layers (OS, dependencies) before frequently changing layers (app code) — maximum cache utilization.
- .dockerignore: Exclude node_modules, .git, tests, and documentation from the build context.
- Combine: Consolidate multiple RUN commands into a single layer to avoid intermediate layers.
Results
Using these techniques, we reduced the image size from 1.2 GB to 45 MB in a client project. Build time dropped from 8 to 2 minutes, and deployments are three times faster.
Questions About This Topic?
We are happy to advise you on the technologies and solutions described in this article.
Get in Touch