This post is from a low-reputation account and contains an unverified outbound link. Be cautious before clicking external links.

Reducing Docker image size with Multi-Stage builds

Words
295
Reading
2 min
Listen
Play
8y

When to use Multi-Stage builds

Some Dockerfile's have a lot of development inside. They need building tools, development libraries etc. The result is way to big image.
An other good reason could be security. For instance you need a personal account/key to get your source data and you don't want to leave these in your container.

Docker has a sollution for this, "Multi-Stage" builds.

The basic idea is to use the FROM directive twice (or more). The last FROM can copy files from the first one.

Example Dockerfiles

Build from source example

FROM alpine-sdk as builder
RUN build mypackage

FROM alpine
COPY  --from=builder  /tmp/mypackage.apk /tmp/mypackage.apk
RUN apk add --update --no-cache mypackage.apk
  • In the first FROM our builder gets the label "builder"
  • In the example the builder builds a package in /tmp/mypackage.apk.
  • In the next stage you start with a clean alpine image.
  • After this the result package is copied into the clean alpine
    The label "builder" refers to the previous builder container.
  • The last step installs the package.

Result, only the needed packages are installed and there is no development trash in your container.

Security Example

FROM ubuntu as private
ADD privatekey /root/.ssh/id_rsa
WORKDIR /tmp
RUN scp -i /root/.ssh/id_rsa user@host:~/myproject .

FROM ubuntu
COPY  --from=private  /tmp/myproject /opt
CMD ["/opt/myproject/bin/project"]
  • First we create a private container
  • Then we add our private key to the private container
  • With the key we fetch myproject with scp
  • Myproject is copied in the second empty ubuntu

Result the final container has no private key and myproject.

Multi-Stage Docker tricks

In the examples before the "COPY --from" was used to copy data from the builder.
An other way to use this is to copy files from other docker images

FROM ubuntu
RUN apt update
RUN apt install nginx
COPY --from=nginx:latest /etc/nginx/nginx.conf /etc/nginx/nginx.conf

If you only want to build the builder you could do this

docker build --target builder -t myspecialbuilder

Example projects on github

Documentation

Reducing Docker image size with Multi-Stage builds | Ecency