How to create the smallest working docker image every time? Aim: to create the smallest working docker images every time

Current

REPOSITORY          TAG       IMAGE ID            CREATED             SIZE
a-docker-image      latest    x                   42 minutes ago       1.92 GB


Attempt

Adding a cleanup step at the end of the Dockerfile:

#clean
RUN apt-get purge -y wget
RUN rm -r a-build-dir
RUN apt-get purge -y a-package


reduced the image size a little bit:

REPOSITORY          TAG       IMAGE ID            CREATED             SIZE
a-docker-image      latest    y                   2 minutes ago       1.86 GB


Discussion

I have built various docker images. Every time I try to decrease the size of the created image, but I always feel it is too large. I am looking for a script that has already been created by someone on github that removes all superfluous packages from the image so the size of the created image will be as small as possible.

As I said I always try to reduce the size of the image, but I want to apply this consistent so that every image that I create from now on will be as small as possible.

Question

How to create the smallest working docker image every time?
A Dockerfile creates a new layer for each of the commands in the file. Since layers are well, layered on top of each other - you cannot remove files that a previous layer added. This is why when you install packages, or download files, or create builds each in a separate command - these are still there in the image, even if in a future layer you removed them.

So if you just change this:

RUN apt-get update -y
RUN apt-get install -y wget a-package
# ...
RUN apt-get purge -y wget
RUN rm -r a-build-dir
RUN apt-get purge -y a-package


To this:

RUN apt-get update -y \
    &amp;&amp; apt-get install -y wget a-package \
    &amp;&amp; mkdir a-build-dir \
    &amp;&amp; wget http://some-site/very-big-source-code.tar.gz \
    &amp;&amp; tar xzvf very-big-source-code.tar.gz \
    &amp;&amp; do-some-compilation \
    &amp;&amp; apt-get purge -y wget \
    &amp;&amp; cd .. \
    &amp;&amp; rm -rf a-build-dir \
    &amp;&amp; apt-get purge -y a-package


You will get a much smaller image.



Another option, is to squash the image after you built it.
Q: How does the new docker --squash work?



Yet another option, is to choose a slim base image. For example, images that use Alpine Linux as their base instead of Debian, take just 10-15mb instead of 180-250mb. And this is before adding your own application and data. Many official base images on Docker Hub have an alpine version.