Docker + Go で小さいイメージを作成する話

1 min read読了の目安(約1000字

DockerでGoのイメージを使っていますか?
今回はイメージをなるべく小さく利用できるようにしてみました。

検証

とりあえずGoのファイルを作ってみましょう。

package main

import "fmt"

func main() {
  fmt.Println("hello")
}

Debian, AlpineのDockerイメージを作成を作りました。

FROM <golang:1.16-buster or golang:1.16-alpine>
WORKDIR /go/src/app
ADD . /go/src/app

RUN go build -o /go/bin/app

CMD ["/app"]

イメージの大きさ

普通にイメージを使うと以下のように結構でかいです、

上記の画像のようにAlpineもなかなかの大きさなのですが、Goのプロジェクトはサポートしてないそうです。

This variant is highly experimental, and not officially supported by the Go project (see golang/go#19938 for details).

解決策

シンプルに、multi-stage buildしてあげればよいです。

FROM golang:1.16-buster as build

WORKDIR /go/src/app
ADD . /go/src/app

RUN go build -o /go/bin/app

FROM gcr.io/distroless/base-debian10
COPY --from=build /go/bin/app /
CMD ["/app"]

実際にbuildするとこんな感じになります。

まとめ

Dockerで動かすときは小さく動かしたいですが、Goのようにでかいイメージに
なりそうなときはぜひmulti-stageを活用してみてください。