多階段構(gòu)建Golang程序Docker鏡像方法詳解
為什么要多階段構(gòu)建
大家都知道Golang是編譯型語言,源碼需要先編譯再運行,編譯過程中需要下載依賴包,最終編譯成可執(zhí)行的二進(jìn)制文件,只需要部署這個二進(jìn)制文件即可運行。
現(xiàn)在基本都是采用容器化部署方式,打包出的鏡像體積越小越好,和程序運行無關(guān)的東西越少越好。所以打包Golang程序Docker鏡像時,最好的做法是只將編譯好的Golang程序二進(jìn)制文件打包進(jìn)鏡像即可。
如果要做到這一點的話,就需要使用多階段構(gòu)建Docker鏡像方法了。首先基于一個有Golang編譯環(huán)境的基礎(chǔ)鏡像編譯出Golang程序的二進(jìn)制文件,然后將二進(jìn)制文件打包到用于運行環(huán)境的基礎(chǔ)鏡像中。
代碼示例
FROM golang:1.19 AS builder
WORKDIR /project
ADD . .
RUN go build main.go
FROM debian:stable-slim
WORKDIR /app
COPY --from=builder /project/main .
CMD ["./app/main"]
語法非常簡單,需要注意兩個點:
- From,開啟一個新的build階段,可以使用as為當(dāng)前stage指定一個名字,如果沒有指定名字的話默認(rèn)從0開始;
- Copy,默認(rèn)從本地目錄復(fù)制文件或文件夾到docker image,如果有--from,則會從指定的docker stage或其他docker image中復(fù)制,例如--from=builder、--from==0(沒有使用as為當(dāng)前stage命名的情況下默認(rèn)為0)。
小結(jié)
多階段構(gòu)建Docker鏡像有如下幾點好處:
- 減小鏡像體積:多階段構(gòu)建可以在一個Dockerfile文件中使用多個FROM指令從不同的鏡像中構(gòu)建不同階段的鏡像,在最后一階段中只保留應(yīng)用程序所需的文件和運行時環(huán)境,減小了鏡像的大小。
- 提高構(gòu)建效率:在多階段構(gòu)建中,因為只需要在最后一階段中打包需要的文件,從而避免了在構(gòu)建過程中不必要的文件和依賴項,并且避免了為每個構(gòu)建層創(chuàng)建新的容器。
- 更易維護(hù):多階段構(gòu)建可以將不同的構(gòu)建階段獨立出來,從而簡化了維護(hù)過程。如果需要更改其中一個階段,那么只需要改變該階段的Dockerfile文件即可。
- 更安全:多階段構(gòu)建可以避免同時在一個容器中安裝和運行多個不同的應(yīng)用程序和軟件工具所帶來的潛在安全風(fēng)險。