Optimizing Docker Images Using Multistage Builds

Share the page with

In this post I will mention some of the rules and tricks to generate optimized Docker images.

Multistage builds

Multi-stage builds are useful to optimize Dockerfiles while keeping them easy to read and maintain.

By using multistage build technique we can reduce the size of our docker image. The key point to is that we do not need to worry much about bringing in extra resources to build our application, and we can still run a lean production container. Multistage containers also encourage doing builds inside Docker, which is a great pattern for repeatability in your build system.

In the past, it was common practice to have one Dockerfile for development, and another, slimmed-down one to use for production. The development version contained everything needed to build your application. The production version only contained your application and the dependencies needed to run it.

To write a truly efficient Dockerfile, you had to come up with shell tricks and arcane solutions to keep the layers as small as possible. All to ensure that each layer contained only the artifacts it needed, and nothing else.

You can read about the multistage here.

# syntax=docker/dockerfile:1
FROM ubuntu:22.04 as system_builder
USER root
RUN apt-get update && \
apt-get install -y --no-install-recommends gfortran gcc libomp-dev curl git \
python3 python3-pip cmake ninja-build \
liblapack-dev libopenblas-dev libhdf5-dev \
libplplot-dev plplot-driver-cairo libboost-all-dev \
gnuplot doxygen libgtk-4-dev && apt-get clean

FROM system_builder
ENV EASIFEM_BUILD_DIR /easifem/build
ENV EASIFEM_SOURCE_DIR /easifem/src
ENV EASIFEM_INSTALL_DIR /easifem/install
ENV EASIFEM_TEST_DIR /easifem/tests

COPY ./tests/* $EASIFEM_TEST_DIR/

WORKDIR $EASIFEM_TEST_DIR

RUN gfortran -o main.out main.F90 && ./main.out

The first line

# syntax=docker/dockerfile:1

tells Docker that we are going to use a newer version of the Dockerfile frontend which will require BuildKit’s new features.

We can stop the build at particular stage. For example, in the following example, we stop only build the system_builder image.

DOCKER_BUILDKIT=1 docker image build --target system_builder -t vickysharma0812/easifem-system:latest .

Note that we have enable BuiltKit by specifying DOCKER_BUILDKIT=1.

In the line

FROM system_builder

we are using previous stage as new stage.

You can read more about multistage build at official website of docker.

Share the page with