Tips

Docker マルチステージビルドで軽量・安全なイメージを作る

マルチステージビルドは、Dockerイメージのサイズを大幅に削減し、セキュリティリスクを低減する強力なテクニックです。ビルドに必要な環境とランタイム環境を分離することで、最終的なイメージにはアプリケーションの実行に必要な最小限のファイルのみを含めることができます。これにより、CI/CDパイプラインの高速化やデプロイコストの削減にも繋がります。

技術・言語・ツール: Docker

マルチステージビルドは、Dockerイメージのサイズを大幅に削減し、セキュリティリスクを低減する強力なテクニックです。ビルドに必要な環境とランタイム環境を分離することで、最終的なイメージにはアプリケーションの実行に必要な最小限のファイルのみを含めることができます。これにより、CI/CDパイプラインの高速化やデプロイコストの削減にも繋がります。

Docker マルチステージビルドで軽量・安全なイメージを作る

説明

従来のDockerfileでは、ビルドに必要なツールや中間ファイルがそのまま最終イメージに含まれてしまい、イメージサイズが肥大化したり、不要なライブラリによるセキュリティリスクが増大する問題がありました。マルチステージビルドでは、複数の FROM 命令を使用してビルドプロセスを段階的に分割し、最終ステージでは前のステージで生成された成果物のみをコピーして、シンプルで軽量なイメージを構築します。

コード例

# --- ビルドステージ ---
# アプリケーションのビルドに必要な環境
FROM golang:1.22-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/myapp .

# --- 最終イメージステージ ---
# アプリケーションの実行に必要な環境(軽量なランタイム)
FROM alpine:latest

WORKDIR /app
# ビルドステージから成果物をコピー
COPY --from=builder /app/myapp .

EXPOSE 8080
CMD ["./myapp"]

おすすめポイント・注意点

  • イメージサイズの大幅な削減: ビルドツールや開発用ライブラリが最終イメージから除外されるため、ディスク使用量やネットワーク転送量が減ります。
  • セキュリティ向上: 不要なツールや依存関係が最終イメージに含まれないため、攻撃対象領域(Attack Surface)が減少します。
  • ビルドキャッシュの活用: 各ステージは独立してキャッシュされるため、変更がないステージは再ビルドされず、CI/CDパイプラインが高速化します。
  • --from= の活用: COPY --from=ステージ名 を使用して、前のステージから特定のファイルやディレクトリをコピーします。
  • 軽量なベースイメージ: 最終ステージには alpine のような極めて軽量なディストリビューションを使用することで、さらなるイメージサイズの削減が見込めます。
  • デバッグ用ステージの追加: 必要に応じて、開発・デバッグ用の別のステージを設けて、最終イメージとは異なる環境で動作確認することも可能です。