Using multi-stage build to optimize Docker images

2 min read | by Jordi Prats

To be able to build a Docker image we might need some packages that we won't be using at runtime, an example of this would be the compiler or any of the tools we might be using to build it (make, ant, maven...)

Instead of installing the tools to remove them later on while building the Docker image we can use a multistage build so we can just copy the artifacts we need to the final image.

To do so we can use any base image to build the tool:

FROM alpine as build

RUN apk --no-cache add gcc make
RUN gcc -c example.c -o example

FROM alpine

COPY --from=build /example /usr/local/bin/

And them copy what we need to another base image using COPY:

FROM alpine as build

RUN apk --no-cache add gcc make
RUN gcc -c example.c -o example

FROM alpine

COPY --from=build /example /usr/local/bin/

The first part is used just to build the tool, with the final FROM we are defining the final container to which we can copy all the data we need without having to manually write a script to do so.

We can also use the same approach to copy artifacts from already build images, for example, we can just declare an image and then use COPY to copy some of the files it contains, for example:

FROM rclone/rclone AS rclone

FROM python:3.8-alpine

COPY --from=rclone /usr/local/bin/rclone /usr/local/bin/

Posted on 17/01/2022