Docker的多阶段构建
为什么选择多阶段构建?
在学习AWS过程中,我们有机会将Docker部署到ECR或ECS上。通过减小Docker镜像的大小,我们可以实现以下目标:
-
- ECRのようなレジストリへの保管費用を削減
-
- pull時の通信費用を抑えることができる
- ローカルのストレージの圧迫を抑える
由于多阶段建设的优点很大,所以我将公开我在那里学到的东西。
多层次建设是什么?
多阶段构建是指“使用多个阶段进行构建”的方法。
多阶段构建的优点是,通常情况下,Docker镜像中除了应用程序和必要的执行文件外,还包含与镜像构建有关的库等。但是,在生产环境中,我们只想构建应用程序和必要的执行文件。因此使用多个阶段,可以解决这个问题。
ここで、ステージを二つ用意するとします。
一つ目のステージでは、アプリケーションのビルドを行い Docker イメージを作成します。
二つ目のステージでは、一つ目のステージで作成したイメージの中から必要なものだけをコピーしてきます。
このようにステージを二つ用意することで、最終的な Docker イメージには必要なものだけが含まれるようになるのです。
その結果、イメージサイズが小さくなり、本番環境の運用のパフォーマンスが向上します。
具体描述
之前
FROM golang:1.17.1
WORKDIR /go/src/api/
COPY ./ /go/src/app
RUN apt-get update && apt-get install -y vim
RUN go get github.com/rubenv/sql-migrate/... && \
go get github.com/pilu/fresh
CMD go run main.go
EXPOSE 8080
完成
// 中間イメージに当たる
FROM golang:1.17.1-alpine as builder
RUN apk add --update --no-cache ca-certificates git && \
apk add vim && \
apk add --no-cache gcc && \
apk add --no-cache musl-dev
WORKDIR /go/src/api/
COPY ./ /go/src/api
RUN go install github.com/pilu/fresh && \
go install github.com/rubenv/sql-migrate/...
// バイナリファイルを作成する (これが`as dev`にコピーされることでイメージサイズを小さくすることができる)
RUN GOOS=linux \
GOARCH=amd64 \
go build -a -installsuffix cgo -o main main.go
FROM alpine as dev
WORKDIR /go/src/api/
// ここでbuilder(中間イメージ)からバイナリファイルをCOPYする
COPY --from=builder /go/src/api/main /go/src/api/main
CMD [ "/go/src/app/main" ]
EXPOSE 8080