使用scratch構建最小化Go程序的docker image

由于Golang編譯之后的文件是二進制,而scratch是docker最基礎的空image,所以可以使用scratch來構建Go程序的docker image,使得最終構建的image最小化.

構建image過程分為兩步:

    1. 在Go基礎image中build.
    1. 將build好的二進制文件拷貝到scratch image中。

無需cgo的程序

對于無需cgo交叉編譯的程序,使用scratch來作為最終運行的基礎image非常合適。

首先,選擇合適版本的golang基礎image來build,這里沒有必要選擇更小的golang alpine,build過程中pull一般會有緩存所以pull速度差別不大,此外alpine中沒有git和ssl,我們在構建image過程中都有可能用到,況且alpine也不會影響最終image大小。

FROM golang:1.13 AS builder

禁掉cgo交叉編譯,我們服務器一般為linux amd64,build二進制文件。

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /bin/appmain main.go

對于絕大多數go程序而言,是無需root來運行,根據docker best practice,使用non-root來運行程序能夠帶來更好的安全性,所以我們使用non-root用戶來運行,創(chuàng)建一個appuser,之后再拷貝到scratch運行image中。(scratch是空image,所以在builder中創(chuàng)建user,再拷貝。)

# 創(chuàng)建appuser
RUN groupadd -r appuser && useradd --no-log-init -r -g appuser appuser
...
# 拷貝appuser到scratch
COPY --from=builder /etc/passwd /etc/passwd
... 
# 選擇appuser為默認程序運行用戶
USER appuser

多數程序可能會用到ssl,我們將builder中的crt拷貝一下即可。(如果builder是alpine,不能拷貝,需要在alpine中apk先預裝一下。)

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

完整版Dockerfile

FROM golang:1.13 AS builder
COPY . /app
WORKDIR /app
RUN groupadd -r appuser && useradd --no-log-init -r -g appuser appuser
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /bin/appmain main.go

FROM scratch
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /bin/appmain /bin/appmain
USER appuser
CMD [ "/bin/appmain" ]

需要cgo的程序

有些Go程序是需要cgo交叉編譯的,例如ethereum. 對于需要cgo的程序,相對于scratch,更推薦使用alpine來作為基礎image,原因是alpine中帶有l(wèi)ibc,并且體積也才2MB多。而scratch中沒有,當然也可以在builder中l(wèi)dd依賴并拷貝到scratch中。只是用alpine會更方便一些。

在alpine中只要軟鏈接一下就可以使用。

RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2

此外,創(chuàng)建non-root用戶的步驟也沒有必要在builder中進行了,可以直接在alpine中創(chuàng)建。

RUN addgroup -S appuser && adduser -S -G appuser appuser

完整版Dockerfile

FROM golang:1.13 AS builder
COPY . /app
WORKDIR /app
RUN go mod download
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /bin/appmain main.go

FROM alpine:3.10
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /bin/appmain /bin/appmain
RUN addgroup -S appuser && adduser -S -G appuser appuser
USER appuser
CMD [ "/bin/appmain" ]
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容