Go - 多阶段构建docker镜像

1. 概述

对于Golang程序而言,源码需要编译,且在编译过程中还会下载一些依赖的packages,最终生成一个可执行的binary文件。如果使用docker部署,只需要将binary文件放到docker image里面即可,不需要golang源码和依赖的packages。

因此,容易想到的方法:

  • 首先,在本地编译或通过docker编译,将binary文件保存在本地
  • 然后,将binary文件放到新的docker image中,即可生成一个体积较小的docker镜像
  • 最后,部署新的docker镜像到测试环境或生产环境

这种方法比较麻烦,只拷贝一个binary文件,还好。如果来回copy多个文件或文件夹,就不make sense了,例如

  • 前端代码混淆的场景,只需要将混淆后的文件copy到镜像中即可
  • 通过cython编译python代码的场景,将生成一堆so文件(通常用于加密python代码)

上面两个scenario还有一个共性,源码不能出现在最终的docker image的layer中,否则就失去了初心。

这个时候,Multi-stage builds就非常有必要了。

2. 多阶段构建Multi-stage builds

看一个来自docker官方文档的例子:

FROM golang:1.16 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app ./
CMD ["./app"]  

语法还是比较简单的,基本一看就懂,只需要注意两个点:

  • From,会开启一个新的build阶段,如果有as,则为当前stage的name,否则默认从0开始
  • Copy,默认从本地目录复制文件或文件夹到docker image,如果有--from,则会从指定的docker stage其他docker image中复制,例如--from=builder--from==0--from==nginx:latest

3. 其他用法

关于多阶段构建镜像,docker官方还提供了一些其他玩法,可以根据需要灵活选择。

3.1. 只构建特定stage的docker image

通过--target指明stage name,build该stage后将停止构建。

A few scenarios where this might be very powerful are:

  • Debugging a specific build stage
  • Using a debug stage with all debugging symbols or tools enabled, and a lean production stage
  • Using a testing stage in which your app gets populated with test data, but building for production using a different stage which uses real data
docker build --target builder -t alexellis2/href-counter:latest .

3.2. 引用已定义的stage作为from源

# syntax=docker/dockerfile:1

FROM alpine:latest AS builder
RUN apk --no-cache add build-base

FROM builder AS build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp

FROM builder AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp

4. 参考

Multi-stage builds | Docker Documentation

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容