マルチステージビルド
イメージは軽量であることが重要です。
コンテナを起動するためにはレジストリからイメージをpullしてから立ち上げる必要がありますが、巨大なイメージはpullに時間がかってしまいコンテナを起動するためのリードタイムが長くなります。
リードタイムが長くなることにより様々なリスクが伴います。
* デプロイ・ロールバックが遅くなる。
* スケールアウトが遅くなりコンテナの起動が間に合わずにリクエストを捌けなくなる。
* 巨大なイメージを保存するためにレジストリの保存領域もしくは保存料が高くなる。
軽量なイメージをビルドするための機能がマルチステージビルドで、複数のイメージから1つのイメージをビルドするための技術です。
例えばgolangであればバイナリファイルのみで実行が可能なため、ビルドレイヤーでバイナリを生成し、最終イメージは軽量なベースイメージを使用することで軽量なイメージをビルドすることが可能です。
以下がそのサンプルになります。
バイナリをビルドする Builderイメージ と、Builderイメージで生成したバイナリをコピーし実行する Runnerイメージ の2つからなるマルチステージビルドの例です。
# syntax=docker/dockerfile:1
# === Builder
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
# === Runner
FROM busybox AS runner
WORKDIR /app
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "1001" \
app
USER app
COPY --from=builder --chown=app:app /app/main /bin/main
EXPOSE 8080
CMD ["main"]
これにより、最終イメージは Builderイメージ のバイナリを所有した軽量な Runnerイメージ が作成できます。
--target
オプションで中間イメージを指定することで、中間イメージのみをビルドすることも可能です。