【Docker】Goのプログラムをマルチステージビルドして動かす

マルチステージビルドとは

マルチステージビルドとは、Dockerイメージをビルドする際に複数のコンテナ、ステージを使用する手法です。基本的に最初のステージでビルドや依存関係の解決を行い、最終のステージではコンテナに実行ファイルとその他実行に必要なものだけを入れるようにします。

これにより、最終的なDockerイメージのサイズを小さく抑えることができます。

:::note info 基本的にコンテナの考え方としてコンテナの中には余分なものがないことが望まれています。セキュリティ的な面だけでなく、CI/CDだったりpull pushなどのいろいろな面で軽量であったほうが良いからです :::

マルチステージビルドという用語から、この手法はコンパイル・ビルドがあるCやRustなどの言語だけで利用できる手法かと思われがちですが、PythonやPHPなどのランタイムを必要とする言語でも軽量化を行う目的で利用されることがあります。

Dockerfileを書く

以下はGoのプログラムをマルチステージビルドでDockerイメージにするためのDockerfileの例です。 実際に動かすプログラムは何でも大丈夫です。

dockerfile
Copy code
FROM golang:1.21-alpine as builder

WORKDIR /app/

COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY . .
RUN go build -o main .

FROM alpine:latest

WORKDIR /app/
COPY --from=builder /app/main /app
RUN chmod +X main
CMD ["./main"]

このDockerfileでは、最初のステージでGoのコンパイルを行い、次のステージでコンパイル済みのバイナリを軽量なAlpine Linuxベースのイメージにコピーしています。これにより、最終的なイメージのサイズが小さくなります。

実際にはこの部分でbuiderコンテナからバイナリをコピーしてきています。

COPY --from=builder /app/main /app

ビルドして動かしてみる

上記のDockerfileを用いてイメージをビルドするには、以下のコマンドを実行します。

docker build -t my-go-app .

ビルドが完了したら、次のコマンドでコンテナを実行できます。

docker run --rm my-go-app

これにより、マルチステージビルドで作成したGoのプログラムがDockerコンテナ内で動作します。