- Blog/
How to Create Multi-stage Dockerfile
Table of Contents
Introduction #
A Dockerfile is a document that contains all the instructions to build an image. Basically, you create an image on top of the existing image with given specifications on the Dockerfile. Then Docker will take this file and follow your instructions to create a brand new image on top of the base image.
A base image is an image built by other users. Usually, the base image is a
fundamental OS image. For example alpine
or ubuntu
. The base image gives you a base that you can instruct. Usually,
we install our custom packages on top of the base image. However, we
need multiple base images based on different needs.
Prerequisites #
docker
What is multi-stage #
Say that you have Go
project and you need to build it. For this case, you
will need some packages only required for the build itself we do not want
to keep these packages in our image just for build purposes.
Multi-stage Image Example #
That is the reason that we need to use multi-stage to reduce our image size. Let’s create an image for an example:
FROM golang:1.17-alpine3.14 AS builder
WORKDIR /app
COPY ./ /app
RUN apk update && \
apk add ca-certificates gettext git make curl unzip && \
rm -rf /tmp/* && \
rm -rf /var/cache/apk/* && \
rm -rf /var/tmp/*
RUN go build -o my-binary main.go
In this Dockerfile
example, we are building main.go
file to binary. As
you can see we are installing a bunch of other packages for building purposes
but we do not need them for later usage of the image. This Dockerfile
creates an image sized 572MB
.
Let’s improve the Dockerfile
to adapt it to use multi-stage.
FROM golang:1.17-alpine3.14 AS builder
WORKDIR /app
COPY ./ /app
RUN apk update && \
apk add ca-certificates gettext git make curl unzip && \
rm -rf /tmp/* && \
rm -rf /var/cache/apk/* && \
rm -rf /var/tmp/*
RUN go build -o my-binary main.go
FROM alpine:3.14
COPY --from=builder /app/my-binary /bin/my-binary
ENTRYPOINT ["my-binary"]
We added another FROM
which creates another stage with base image alpine
and copies the binary from the previous stage called builder
and put it to
/bin/my-binary
path.
The new image size with multi-stage Dockerfile
is 7.36MB
. So, we only
get the binary from the previous stage called builder
the other packages that
we installed for building the binary is not included in our final stage.
Conclusion #
We install lots of other packages on the base image to build staff. But, we
do not always need those packages in the final image. Multi-stage
Dockerfile
helps us to reduce the image size dramatically from 572MB
to
7.36MB
.