よく忘れるので、ここにメモメモ。。。
マルチステージビルドを利用すると、ビルド時のステージと実行時のステージを分けることが出来るので
余計なものが入っていないイメージをつくることが出来ます。
さらに、Googleが管理しているDistrolessイメージをベースにすることでさらに小さなサイズにすることが出来ます。
Distrolessイメージにはシェルすらも入っていないのでセキュリティ的にも良しですね。
DistrolessイメージはGoと相性がいいので、今回はGoのプログラムをコンテナの中で実行するようにします。
helloworldだけを普通に出力するプログラムだとimportされるパッケージが少ないので、少しだけ非同期入れて出力するようにしたプログラムです。
処理の内容に意味はありません。
package mainimport ("context""fmt""time""github.com/devlights/gomy/ctxs""github.com/devlights/gomy/iter")func main() {var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx,1*time.Second) )defer mainCxl()defer procCxl() <-exec(procCtx).Done()}func exec(pCtx context.Context) context.Context {var ( tasks =make([]context.Context,0,5) )for i :=range iter.Range(5) { tasks =append(tasks,func(pCtx context.Context, iint) context.Context { ctx, cancel := context.WithCancel(pCtx)gofunc() {defer cancel()select {case <-ctx.Done():breakdefault: fmt.Printf("[%d] hello-go\n", i+1) } }()return ctx }(pCtx, i)) }return ctxs.WhenAll(pCtx, tasks...)}
alpineベースのイメージを使いました。
# syntax=docker/dockerfile:1-labsFROMgolang:1.17-alpineWORKDIR/workspaceENVCGO_ENABLED=0COPYgo.* .RUNgo mod downloadCOPY. .RUNgo build -o app main.goCMD["/workspace/app" ]
ビルドステージは alpineベースのものを使って、実行時はDistrolessを使っています。
# syntax=docker/dockerfile:1-labs# -----------------------------------------------------# base image# -----------------------------------------------------FROMgolang:1.17-alpine as baseWORKDIR/workspaceENVCGO_ENABLED=0COPYgo.* .RUNgo mod downloadCOPY. .RUNgo build -o app main.go# -----------------------------------------------------# runner image# -----------------------------------------------------FROMgcr.io/distroless/static:latestWORKDIR/appCOPY--from=base /workspace/app appCMD["/app/app" ]
何回もコマンド打つのが面倒なので make できるようにしました。
build:\copy-gomod\build-nostage\build-multistage\rm-gomodcopy-gomod: cp ../go.* .rm-gomod: rm go.*build-nostage: docker buildx build -t multistage-ex:nostage -f Dockerfile.nostage${PWD}build-multistage: docker buildx build -t multistage-ex:multistage -f Dockerfile.multistage${PWD}run: time -p docker container run --rm multistage-ex:nostage time -p docker container run --rm multistage-ex:multistageclean: docker image rm multistage-ex:nostage multistage-ex:multistage docker image prune -f
$ make builddocker buildx build-t multistage-ex:nostage-f Dockerfile.nostage /workspace/try-docker/multistage_builddocker buildx build-t multistage-ex:multistage-f Dockerfile.multistage /workspace/try-docker/multistage_build
$ docker image list multistage-exREPOSITORY TAG IMAGE ID CREATED SIZEmultistage-ex multistage bde4552a21c841 seconds ago4.33MBmultistage-ex nostage edc5dfebefbf52 seconds ago 376MB
マルチステージなしの場合は 376MB で、マルチステージありの場合は 4.33MB となっていますね。
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。