How to Reduce Docker Image Size: From Gigabytes to Megabytes
Learn proven techniques to shrink Docker images by up to 90% using multi-stage builds, slim base images, and proper layer ordering.

Stock photo for illustration only, not from the actual event
- Cut Docker image sizes by up to 90% without changing app code
- Leverage multi-stage builds to exclude development toolchains
- Order Dockerfile instructions from least to most volatile
- Use .dockerignore to exclude junk and prevent secret leaks
Docker image size is far from a mere aesthetic concern. Every gigabyte requires extra bandwidth during deploys, consumes host storage, and expands the attack surface by packing unnecessary packages and CVEs. Achieving a 90% size reduction is completely routine through four core techniques that require zero changes to your actual application code.
The heavy hitter is Multi-stage builds. This approach builds your project inside a full toolchain image, then copies only the final production artifacts into a minimal runtime stage. Compilers, development dependencies, and source code never make it to production.
Implementing multi-stage builds significantly tightens production security by shrinking the attack surface, ensuring that build-time vulnerabilities and developer utilities are entirely absent from your production deployment nodes.
Another crucial practice involves layer ordering and utilizing .dockerignore. Docker caches layers strictly from top to bottom, invalidating everything below the moment a change occurs. Ordering instructions from least volatile to most volatile—such as installing dependencies before copying source code—ensures code edits never force re-downloading dependencies.

Stock photo for illustration only, not from the actual event
Additionally, always ship a .dockerignore file to shrink the build context, keep junk out of your image layers, and stop secrets like .env files or node_modules from leaking into image history.
The final golden rule is to measure rather than guess. Tools like docker history or the dive utility reveal exact layer sizes and expose wasted space caused by adding and deleting files across separate steps. Always combine cleanup operations within the exact same RUN instruction, such as appending rm -rf /var/lib/apt/lists/* to package installations.
Applying these optimizations transforms a naive 1.1 GB Node/Next.js application down to 130–180 MB, slashes Python/Django apps from 950 MB to roughly 180 MB, and shrinks Go services down to a mere 8–15 MB. Operationally, deployments shift from transferring minutes of data down to seconds while rollbacks become instantaneous.
Source: Dev.to
Found something wrong in this article? Report an issue with this article
Comments
Leave a Comment