How to make Docker images smaller
Github: nturaga; Twitter: niteshturaga
Trying to make Docker images smaller is a little bit easier if you know how the filesystem works and have a few handy resources.
My first naive effort, I was trying to delete stuff from the top layer of a 5Gb image (with plenty of layers). Once I saved the image, the size was almost exactly the same. Nothing changed. WHAT?
How does the Docker file system work?
Docker works using layers of images. Docker uses one of the two file systems depending on your Linux kernel.
- AUFS is a union filesystem.
To find out which one your
docker engine is using,
❯❯❯ docker info | grep Storage
Storage Driver: overlay2
If you try just
docker info you’ll see plenty of great information which is very useful, including my favorites such as (this is a shorter list)
Kernel Version: 4.9.125-linuxkit
Operating System: Docker for Mac
Total Memory: 7.787GiB
Docker Root Dir: /var/lib/docker
What is overlay2?
Overlay2 (overlayFS) is a modern union filesystem that is similar to AUFS, but faster and with a simpler implementation.
A union filesystem, layers multiple directories on a single Linux host and presents them as a single directory. So, all your layers give the appearance of being unified in the “top” writeable layer of the container. It’s not really all at the top level.
To know which layers are the largest on your image, (more info on docker history)
docker history <image name>:<tag>
This information is useful to identify which layers exactly are adding to the size of your image. Once you identify the line in either your top level Dockerfile or any of the inherited Dockerfile’s, you can try and fix that specific image where that command is coming from.
Deleting files and directories
When you delete a file or a directory from a container, the reason it does NOTHING to change the size of the layers below is:
- When a file is deleted within a container, a whiteout file is created in the container layer. The version of the file in the image layer is not deleted (because the image layers are read-only). However, the whiteout file prevents it from being available to the container.
- When a directory is deleted within a container, an opaque file is created in the container layer. This works in the same way as a whiteout file and effectively prevents the directory from being accessed, even though it still exists in the image layer.
Resources to (potentially) reduce image size
- The website, fromlatest.io (https://www.fromlatest.io/#/), allows you to paste your
Dockerfileand it’ll point at optimization locations in the
- Do not install the same package/library a second time. If the image underneath has it in some layer, it is available to you* (given the right permissions). If you install again, a new layer is added and the size of your image goes up.
- Consider using a
apt-getinstalling packages. This will result in a smaller image size.
- Consider using
rm -rf /var/lib/apt/lists/*to every line you do an
apt-get updateor at least once at the end of your Dockerfile.