SoFunction
Updated on 2025-03-09

Implementation of Docker multi-stage mirror construction

Since Docker version 17.05.0-ce, a new method of building images is supported, called Multi-stage builds, aiming to solve some pain points in Docker build application containers. In daily container construction scenarios, you often encounter source code acquisition, compilation and generation in the same container, and finally build it into a mirror. The disadvantages of doing this are:

  1. Had to install the runtime environment necessary to build the program in the container
  2. Had to get the source code of the program and some ecological tools needed to build it in the same container
  3. The built image even contains the program source code and some unnecessary files, resulting in the container image size being too large.

Of course, there is another slightly elegant way, which is to package the project and its dependency library compilation tests externally before copying them to the build directory. Although this can avoid the risks in the first method well, it also needs to consider the differences in program operation compatibility when running different images.

In fact, Docker also thought of these pain points, and the official provides a simple multi-stage build solution. The so-called multi-stage construction means that the construction process is divided into multiple stages. In the same Dockerfile, the required application files are built and generated through different stages, and finally these application files are added to a release image. Doing so can completely avoid the series of problems encountered above. Implementing multi-stage construction mainly depends on newly provided keywords: from and as .

Here is a chestnut:

FROM muninn/glide:alpine AS build-env
ADD . /go/src/my-proj
WORKDIR /go/src/my-proj
RUN go get -v
RUN go build -o /go/src/my-proj/my-server

FROM alpine
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build-env /go/src/my-proj/my-server /my-server
EXPOSE 80
CMD ["my-server"]

A multi-stage Dockerfile looks like it merges two or more Dockerfiles together, which means multi-stage. The as keyword is used to give an alias to the build stage, so that in another build stage, the build output of the corresponding keyword stage can be referenced and used through the from keyword and packaged into a container.

After the multi-stage construction is completed, the output image only contains the final output my-server application, and there are no other source files and third-party source code packages, which are very clean and concise. Because the build-env stage is just an intermediate process of construction.

We can even use more build stages to build different applications, and finally merge these build output applications into a mirror that needs to be released. We can look at a more complicated chestnut:

from debian as build-essential
arg APT_MIRROR
run apt-get update
run apt-get install -y make gcc
workdir /src

from build-essential as foo
copy src1 .
run make

from build-essential as bar
copy src2 .
run make

from alpine
copy --from=foo bin1 .
copy --from=bar bin2 .
cmd ...

The benefits of multi-stage construction are self-evident. It is easy to easily build the desired container image through a Dockerfile, and there is no need to worry about the risks of too large images or source code leakage. I have to say that this is a very good improvement.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.