美文网首页Go
Go - 多阶段构建docker镜像

Go - 多阶段构建docker镜像

作者: 红薯爱帅 | 来源:发表于2023-04-24 22:56 被阅读0次

    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

    相关文章

      网友评论

        本文标题:Go - 多阶段构建docker镜像

        本文链接:https://www.haomeiwen.com/subject/lwdejdtx.html