Minuscule Images

Back to my obsession with creating small images.

Originally, I wanted to see how these distroless images were built. The distroless project makes use of Google’s bazel build tool. However, setting up Bazel and writing my own images required a bit of work (and let’s be honest, re-inventing the wheel can be extremely fun and educative). I wanted to be able to create smaller images more easily, the act of making an image should be extremely simple, it should be trivial. No configuration files, just one line in the terminal: just build an image for <application> .

Now, if you want to build your own images, you should be aware of a unique docker image: scratch . Scratch is an ‘empty’ image — it does not contain any files (though, it is a whopping 77 bytes by default).

A scratch image

The idea of a scratch image is that we can copy any dependencies in from our host machine and either use these dependencies inside the Dockerfile (like copying in apt and installing dependencies from scratch) or later when the Docker image is materialized. This gives us full control of what we put inside our Docker container, and thus, also full control of the size of the image.

Now, we need some way to gather these dependencies. Existing tools like apt allow you to download packages but they are only constrained to your current machine and, after all, would not support Windows or MacOS.

So, I set out to build my own tool that would be able to automagically build the smallest possible base image to run any application. I would use Ubuntu/Debian packages, fetch them (accessing the package servers directly), and recursively find their dependencies. The tool should always download the latest version stable version of a package, mitigating as many security risks as possible.

I called the tool fetchy , because… it fetches… things… The tool works through a command line interface, though, it also offers an API.

In order to build an image with fetchy (let’s take Python here), all you have to do is use the CLI as follows: fetchy dockerize python . You may be prompted for your target operating system and codename, as fetchy can only use Debian and Ubuntu-based packages for now.

Now, optionally, some dependencies may not be used at all (in our context), and we could also exclude them. For example: Python depends on perl, though, Python will run fine without Perl installed.