Optimize Docker Image via Multi-Stage Builds

Image for post
Image for post

Docker is a great tool that provides to run your application isolated in a container. That also allows you to build, run, and test the application independently from your host machine. For more, please see detailed docker documentation. We will focus on optimizing your Dockerfile so that you get as much as possible a lightweight container. There are many approaches to optimize your Dockerfile, but I will focus on the multi-stage build in docker in this post.

Multi-stage builds are part of the docker since version 17.05. It let you keep your image smaller and easy to maintain.

Let’s begin and see how to do that. In one of my previous posts, I’ve set up Clang 10 in a docker container. Clang is a C/C++ compiler. We will use that image and additionally add another tool such as ninja-build. Ninja is a small build system for also C/C++ applications that focused on speed.

Let’s go through the Dockerfile, respectively. In the first stage, I called it clang-stage, but you may call it whatever you want. We will download and install clang 10 and extract prebuilt binaries to the clang-10 directory that we created.

In the second stage, I called it ninja-stage, we will install the required dependencies to compile ninja that we cloned from GitHub. Also, we work in the/tmp directory.

In the last, which is the main stage, we use ubuntu.18.04 as the base image. In case you need another ubuntu version, then see here.

From now on, we copy clang binaries from clang-stage and ninja binary from ninja-stage to our main-stage. As you noticed, the syntax is straightforward and no complex structure.

Now we can build our image as below: Note that it will take 1–2 minutes.

We could verify the installation of tools easily via the starting container and checking version.

Hence, this post's name is optimization; let’s see how much we could optimize our image. To compare that, I also build an image without a multi-stage build, installed clang 10 and ninja in a docker image. I named it clang-ninja.

As you see, the optimized image 0.66 GB (660MB) is smaller than the non-optimized image. Still, for an image over 1 GB is really big. It might make a huge difference in a different application. For instance, you an application that uses only static binary, then the optimization might be fascinating. For sure, you could optimize Dockerfile further, but this is not focused on this post. So I wish you a happy Sunday!

Computer Science And DevOps things :)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store