How to Keep Docker Images Lean (Part 1 of 3)

Posted by Ken Hayes on September 28, 2018

If you are like me, you have discovered the joy of docker and the power of creating custom containers to meet your needs. For anything from small, replicable servers to large scale CI/CD pipelines, docker containers are powerful tools.

You’ve tested your container and it works. It’s time to move the image to where it is needed. As you sit, watching your image transferring to its new home, you wonder, “Why is this image so large?

In many cases, image size is an afterthought. The good news is, you can minimize image size even after you have it working with these simple techniques:

  • Choose a smaller base image
  • Minimize the image layers
  • Use multi-stage builds

In this first post, let’s focus on your base image.  There are a lot of options out there, and in many cases, more than one will meet your needs. We all have an image preference based on our experiences, but do you really need everything that image has to offer? It may be possible to accomplish your goal with a smaller base image — with some tweaking, of course.

A quick list of some of the more common base images shows their size differences:

$ docker images
debian              latest 9a5d7185d3a6     7 days ago 101MB
ubuntu              latest 113a43faa138     4 weeks ago 81.2MB
centos              latest 49f7960eb7e4     4 weeks ago 200MB
fedora              latest cc510acfcd70     2 months ago 253MB
alpine              latest 3fd9065eaf02     5 months ago 4.15MB

Alpine is small. Therefore, if I can accomplish the goal by adding the necessary components to Alpine, then I will choose that as my base image. It clearly has the size advantage.

In some cases, there are options available even within a single image. Python is a great example.

$ docker images
python              alpine f5cdcff7bf21     15 hours ago 94.7MB
python              slim 5f87764f9df0       15 hours ago 143MB
python              latest ce54ff8f2af6     15 hours ago 916MB

Each python image is slightly different, and they are described well on the Python docker hub page. I would much rather choose an image around 100MB, instead of one closer to 1GB.

Granted, you may not have the option or the desire to switch your base image. In that case, the next part of this blog may be of more help.