DEV Community

Cover image for Reducing Docker Image size
Pratik Singh
Pratik Singh

Posted on

 

Reducing Docker Image size

This article will cover the basics to reduce the size of your Docker images.

Prerequisites ✅

  • Understanding of Docker: Here
  • An existing image or an application that needs a Docker image.

🤔 Understanding the Problem

In the world of microservices, most of the production is standing on containers. Images are like the CDs/Flash drives used to play a certain song (application) in your container.
Docker Images are made to bring unity among the developers despite the platform and environment. But obtaining this at cost of memory and speed is not acceptable.

  • Bulkier images take time to get pulled.
  • Increased time to spin up a container using it.
  • It increases the load on the image registry used.
  • With upgrades, it increases and becomes harder to check for vulnerabilities

I ran into the same issue in my pet project Kube-ez. The issue was around reducing the Docker image : Here. This was the first issue I resolved in 2023. Reduced the size by 97%. Turned the image from ~500 MB to 16 MB.


🤷🏻‍♂️ Why solve this Problem?

So what if the Docker image is 6 GB (..ahem Oracle 😑), it still runs right? Don't touch it.

Well, I disagree! Speaking from my experience as a Site Reliability Engineer at Juspay (Indian Fintech Startup). When there is a service that is running in production. Keeping it up and running is always a majority challenge. But let's agree that no company has an SLO of 100%. Each second of downtime counts!

Someday or the other the service is bound to crash o run into any error. In the best-case scenario, you will be updating it someday. That day you have to spin up a new container or an updated container, that's the day it helps!

A lighter Docker Image ensures that containers will spin up faster and thus saves precious seconds for your company!
Also, it's easier to debug, secure, and store :)


🐋 How to reduce the Docker Image Size?

Well, there are two approaches I found, and will be sharing both of them.

1. Docker Slim ✨

Docker Slim is the best and easiest tool to solve this problem.
Thanks to my friend Mritunjay, for introducing me to this tool.

  • Easily reduce the size of your Docker Images.
  • Connects to DockerHub and gives you an easier platform to handle images on the registry.
  • It also checks and fixes vulnerabilities 🤯
  • Installation and usage are super easy too!

If you wish to slim the size of a local Docker Image, try this article by RedHat Developer Group: Here.
Although, I would love to see apk and other package installation methods in the future.

Image description

Th results I got for the same Docker Image using the tool


2. Manual Approach 💪

Now, this requires a good understanding of your project. There are further two steps in this well. You could stop after the first step if it suffices your needs. Let's get digging!

2.1 Using Lighter Base Images

This is the easiest and the first way to go for. Use a lighter image as a base layer for your container. You could go for an Alpine image of the OS or the language you are using.

Alpine Image: Images with basic barebone OS. It misses essential software and drivers like graphics, wifi, and more.

2.2 Multistage Build

The idea is to use two different stages in the image. One is to build the binary and the next is to simply use it!
Easier said than done 😅

In my case, I applied a multistage build pattern. Made a binary on the build stage and used it to run the container.
Now the image size was: ~35 MB. Further reduced the size of the binary further and finally got a size of around 16 MB.

There are multiple suggestions to include even after this. But I haven't implemented them yet.

  • Include a .dockerignore file.
  • Reduce unnecessary dependencies.
  • Caching layers to reuse

I will keep on adding more ways as I find them.

If you liked this content you can follow me or on Twitter at kitarp29 for more!

Thanks for reading my article :)

Top comments (22)

Collapse
 
ervin_szilagyi profile image
Ervin Szilagyi

If you really need to shrink the size of a Docker image instead of Alpine you may want to use a distroless image. Moreover, if you have only one executable to dockerize and you don't need to emulate an OS environment, you can use the scratch image and runt the executable as PID 1.

Collapse
 
kitarp29 profile image
Pratik Singh

Will try that on next time!
Thank you so much for sharing :)

Collapse
 
lankavitharana profile image
Rajith

yeah, I have tried some of these approaches, the best result I got was with scratch, with that, service in go in docker is reduced to ~8mb (just the executable only), I did the same with Rust as well, and got that reduced even more AFAIR, if you use scratch as the base image(scratch means empty, IE you only pack the executable to the docker image, that essentially means, it's mostly upto the compiler to reduce the executable size, with go and Rust, it is easy to do), you will have to cross compile and both go and Rust has compiler flags to do that

Thread Thread
 
kitarp29 profile image
Pratik Singh

That's great! Thanks Rajith for sharing this insight.
Hope this article helped :)

Collapse
 
cloutierjo profile image
cloutierjo

Also, one of the most neglected part is to condensate run statement, if you have 10 command to execute, running them all in a single RUN will create only one layer, bonus point if some of those command create temporary files, you can erase them at the end of that RUN, they won't be present at all in the final image. In particular Linux update can get a major gain since you can delete the package cache, index and the repo index that are totally useless once the update is completed.

Collapse
 
kitarp29 profile image
Pratik Singh

Will give it a try!

Collapse
 
bcostaaa01 profile image
Bruno

You can also achieve that by using a container registry, which can automatically compress images, hence reducing their size.

Reducing the size of a Docker image helps massively reducing the download time and much less storage, which is the main idea of your article.

Great article in general, fellow writer @kitarp29!👏

Collapse
 
kitarp29 profile image
Pratik Singh

Thanks Bruno! I will keep that in mind.
Your kind words means a lot ot me :)

Collapse
 
pavanbelagatti profile image
Pavan Belagatti

Amazing post Pratik.

Collapse
 
kitarp29 profile image
Pratik Singh

Thank you Pavan

Collapse
 
mfurmaniuk profile image
Michael

We're about to do this with the images we build at work, so this is very timely.

Collapse
 
kitarp29 profile image
Pratik Singh

I am glad I could help :)
Thanks for reading my article 😃

Collapse
 
shoaib19 profile image
محمّد شعیب

Great article🔥

Collapse
 
kitarp29 profile image
Pratik Singh

Thanks 😌

Collapse
 
amykhar profile image
amykhar

Very practical advice. Thank you.

Collapse
 
kitarp29 profile image
Pratik Singh

Thanks :)
Hope it helps!

Collapse
 
yrs147 profile image
Yash Raj Singh

Really insightful Blog Pratik

Collapse
 
kitarp29 profile image
Pratik Singh

Thanks! Hope it helped :)

Collapse
 
nikki_eke profile image
Nikki Eke

Quite insightful Pratik, thanks for sharing!

Collapse
 
kitarp29 profile image
Pratik Singh

Thanks Nikki!
Hope it helps 😊

Collapse
 
shirome9 profile image
SHiRoMe9

Thank you for the article! Just curious which is slim reduction of Docker to make this big difference size?

Collapse
 
veerreshr profile image
Veeresh

Great post, it would be helpful if you included some stats like how much time it took to spin container with older and newer image.

An Animated Guide to Node.js Event Loop

>> Check out this classic DEV post <<