最佳實踐:這才是構建 Go 語言 Docker 鏡像該有的姿勢
本文通過 Go 語言的 Hello World 來介紹基于 Docker 的 Single build 及 Multiple build。
Single build
下面是 Go 語言 Hello World 代碼:
package?main
import?"fmt"
func?main()?{
????fmt.Println("Hello?World!")
}
接著用 alpine[1] 的 Go 語言 Image 來編譯出可執(zhí)行文件。
FROM?golang:alpine
WORKDIR?/app
ADD?.?/app
RUN?cd?/app?&&?go?build?-o?app
ENTRYPOINT?./app
接著執(zhí)行如下編譯指令:
$?docker?build?-t?appleboy/go-app?.
$?docker?run?--rm?appleboy/go-app
最后檢查看看編譯出來的 Image 大小,使用docker images | grep go-app,會發(fā)現(xiàn)大小為 258 MB
Multiple build
Multiple build 則是可以在Dockerfile使用多個不同的 Image 來源,請看看底下例子:
#?build?stage
FROM?golang:alpine?AS?build-env
ADD?.?/src
RUN?cd?/src?&&?go?build?-o?app
#?final?stage
FROM?alpine
WORKDIR?/app
COPY?--from=build-env?/src/app?/app/
ENTRYPOINT?./app
從上面可以看到透過AS和--from互相溝通,以前需要寫兩個 Dockerfile,現(xiàn)在只要一個就可以搞定。
$?docker?build?-t?appleboy/go-app?.
$?docker?run?--rm?appleboy/go-app
會發(fā)現(xiàn)最后大小為 6.35 MB,比上面是不是小了很多。
最小 Image
6.35 MB 是最小的 Image 了嗎?一個簡單的 Hello World 可執(zhí)行文件,用 Docker 包起來竟然要 6.35,其實不用這么大,我們可以透過 Dokcer 所提供的最小 Image:scratch[2],將二進制文件直接扔進去即可,在編譯可執(zhí)行文件時需加入特定參數(shù)才可以:
$?CGO_ENABLED=0?GOOS=linux?GOARCH=amd64?go?build?-o?app
在通過 Docker 包起來:
FROM?centurylink/ca-certs
ADD?app?/
ENTRYPOINT?["/app"]
編譯出來大小為:1.81MB,相信這是最小的 Image 了。
注:centurylink/ca-certs 是一個基于 Docker 的基礎鏡像,它基于 scratch[3] 鏡像構建,并為所有標準證書頒發(fā)機構添加了根證書。
完整的 Dockerfile:
#?build?stage
FROM?golang:alpine?AS?build-env
ADD?.?/src
RUN?cd?/src?&&?CGO_ENABLED=0?GOOS=linux?GOARCH=amd64?go?build?-o?app
#?final?stage
FROM?centurylink/ca-certs
COPY?--from=build-env?/src/app?/
ENTRYPOINT?["/app"]
總結
Multiple build 非常方便,這樣就可以將多個步驟全部合并在一個 Dockerfile 處理掉,像是底下例子:
from?debian?as?build-essential
arg?APT_MIRROR
run?apt-get?update
run?apt-get?install?-y?make?gcc
workdir?/src
from?build-essential?as?foo
copy?src1?.
run?make
from?build-essential?as?bar
copy?src2?.
run?make
from?alpine
copy?--from=foo?bin1?.
copy?--from=bar?bin2?.
cmd?...
用一個 Dockerfile 產(chǎn)生多個可執(zhí)行文件,最后再用 alpine 打包成 Image。
本文作者:AppleBoy
原文鏈接:https://blog.wu-boy.com/2017/04/build-minimal-docker-container-using-multi-stage-for-go-app/
參考資料
alpine: https://hub.docker.com/_/alpine/
[2]scratch: https://hub.docker.com/_/scratch/
[3]scratch: https://registry.hub.docker.com/u/library/scratch/
推薦閱讀
站長 polarisxu
自己的原創(chuàng)文章
不限于 Go 技術
職場和創(chuàng)業(yè)經(jīng)驗
Go語言中文網(wǎng)
每天為你
分享 Go 知識
Go愛好者值得關注
