Docker — a race for smallest image

If you’ve ever met a developer using Docker to pack and run their application, you may have heard complaints about building their distribution image. Base images are always too big (nightmares including everything that surpasses a couple of hundred of Mb), build times very high and so on.

In the Docker world, size matters. Why? Because deploying and updating a Kubernetes cluster, for example, means that size will be individually downloaded by each node.

But it’s not just megabytes we’re talking about. Another important issue is the layer count. Why? Because when you download an image, each layer requires a connection, a download step before they are individually unarchived and made ready for use. More layers means more download time, more overhead.

So if you’re joining the race to the bottom, what are your best bets?

ubuntu:latest => 84.11 Mb (bionic) — xenial was the most downloaded base image, bionic is not only following in its footsteps but also having a much smaller footprint! Formerly 115 Mb for xenial and 188 for trusty, Ubuntu seems to be getting faster and smaller.

centos:latest => 299.72 Mb (7) — the lighter RedHat has been long considered a bastion of stability (if by stability you mean older kernels and lack of access to useful packages). With you being a fat package manager, it’s no wonder centos is the fattest of the bunch and getting fatter by iteration (version 6 was around the 194 Mb mark, 7.2 around 194.63 Mb).

alpine:latest => 4.41 Mb (3.8) — touted as tiny at 5 Mb, the guys developing Alpine have outdone themselves with the latest iteration going well under that limit. Packing a package manager as well (unlike busybox), your images will probably end up with tons of layers but likely a small image.

debian:latest => 100.57 Mb (stretch) — stretch has been here a while in the good Debian tradition of being more stable than Ubuntu but not as chronically entrenched as centos. When you need deb’s and apt but cower at the sound of updates, you may need to look at Debian. At 100 Mb isn’t not too shabby.

debian:stretch-slim => 55.27 Mb — if you want the above but aim at the smallest deb world footprint, just choose Slim.

busybox:latest => 1.16 Mb (1.29) — the Linux toolbox is smaller than ever, but don’t dream of layering much on top of it.

When it comes to Docker, I’ve long been an Ubuntu devout. They say the best tool is the one you know and that does the job. I know Ubuntu and 75% of the time I base my images on it. The rest goes to Debian. In the past it’s been difficult to argue for distros like trusty which were the fat cats of their time but I will never understand anyone preferring Centos for containers (I do when it comes to barebone machines though).

I will end with my recipes for staying small:

  1. Always cleanup your package manager. YUM isn’t as friendly as APT. There’s autoremove but then you should manually remove the cache.
  2. Always remove your downloads. When building from source, always delete leftover build folders, object files and downloaded archives.
  3. Keep your layer count low. Keep singing “Bare necessities” in your head. Don’t use multiple RUN steps to do the same thing, linking several commands in the same RUN is better (and only one thing to cleanup)
  4. If you have multiple RUNs, remember it’s not enough to clean up in the last one. Each layer is independent and must be cleaned independently
  5. Link your commands with && rather than ;. Theres no need to attempt unzip if the download failed.