官术网_书友最值得收藏!

Multi-stage builds

The principles we've discussed so far are all about how to make builds fast and how to make the final image smaller while keeping the maintainability of the Dockerfile. Instead of striving to optimize a Dockerfile, writing one to build the artifacts we need and then moving them to another image with runtime dependencies only makes it much easier to sort the different logic out. In the building stage, we can forget about minimizing the layers so that the build cache can be reused efficiently; when it comes to the release image, we can follow the previously recommended techniques to make our image clean and small. Before Docker CE 17.05, we had to write two Dockerfiles to implement this build pattern. Now, Docker has built-in support to define different stages in a single Dockerfile.

Take a golang build as an example: this requires lots of dependencies and a compiler, but the artifact can merely be a single binary. Let's look at the following example:

FROM golang:1.11 AS builder
ARG GOOS=linux
ARG GOARCH=amd64
ARG CGO_ENABLED=0
WORKDIR /go/src/app
COPY main.go .
RUN go get .

RUN go build -a -tags netgo -ldflags '-w -s -extldflags "-static"'

FROM scratch
COPY --from=builder /go/src/app/app .
ENTRYPOINT ["/app"]
CMD ["--help"]

The delimiter for the different stages is the FROM directive, and we can name the stages with the AS keyword after the image name. At the builder stage, Docker starts a golang base image, and then builds the target binary as usual. Afterwards, during the second build, it copies the binary from the builder container with --from=[stage name|image name] to a scratch image—a reserved name for an entirely empty image. As there's only one binary file and one layer in the resultant image, its size is dramatically smaller than the builder one. 

The number of stages isn't limited to two, and the source of the COPY directive can either be a previously defined stage or a built image. The ARG directive works against FROM, which is also the only exception that can be written before a FROM directive, as they belong to different stages. In order to use it, the ARG directive to be consumed in FROM should be declared before FROM, as shown here:

ARG TAGS=latest
FROM ubuntu:$TAGS
...
主站蜘蛛池模板: 镇赉县| 新宁县| 于都县| 利津县| 禹城市| 新巴尔虎右旗| 崇州市| 当阳市| 沁水县| 修武县| 临高县| 启东市| 民和| 云阳县| 施秉县| 武强县| 兴仁县| 民乐县| 寿阳县| 东光县| 蓝山县| 全州县| 湄潭县| 抚州市| 台前县| 乌兰察布市| 辉县市| 晋宁县| 奈曼旗| 东丰县| 方山县| 新晃| 南通市| 英山县| 高淳县| 探索| 金寨县| 藁城市| 虎林市| 准格尔旗| 多伦县|