- DevOps with Kubernetes
- Hideto Saito Hui Chuan Chloe Lee Cheng Yang Wu
- 398字
- 2021-07-02 13:41:50
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
...
- 數據科學實戰手冊(R+Python)
- 程序員面試筆試寶典(第3版)
- Oracle 12c中文版數據庫管理、應用與開發實踐教程 (清華電腦學堂)
- 三維圖形化C++趣味編程
- 深度強化學習算法與實踐:基于PyTorch的實現
- The DevOps 2.4 Toolkit
- Hands-On Enterprise Automation with Python.
- 正則表達式經典實例(第2版)
- Learning Hunk
- NGINX Cookbook
- Laravel Application Development Blueprints
- Mastering Apache Camel
- Python Social Media Analytics
- Spark技術內幕:深入解析Spark內核架構設計與實現原理
- R語言:邁向大數據之路