マルチステージDockerビルド

マルチステージDockerビルドでより小さく安全な本番イメージを作成。ビルドステージの使用、ステージ間でのアーティファクトコピー、イメージレイヤーの最適化を学びます。

Images

詳細な説明

マルチステージビルド

マルチステージビルドは単一のDockerfileで複数のFROM文を使用します。各ステージは異なるベースイメージを使用でき、最終イメージには必要なアーティファクトだけをコピーします。

基本的なマルチステージパターン

# ステージ1: ビルド
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ステージ2: プロダクション
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]

特定ステージのビルド

--targetで特定のステージまでビルド:

# builderステージのみビルド(テスト用など)
docker build --target builder -t my-app:build .

# productionステージをビルド
docker build --target production -t my-app:prod .

Goアプリケーションの例

マルチステージビルドはコンパイル言語で特に効果的です:

FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server .

FROM scratch
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]

最終イメージにはコンパイル済みバイナリのみが含まれ、Goツールチェーンやソースコードはありません。これにより5〜15MB程度の小さなイメージが生成されます。

キャッシュの最適化

COPY/RUN命令を変更頻度の低いものから高いものの順に配置:

# ロックファイルが変更されていなければこれらのレイヤーはキャッシュされる
COPY package.json package-lock.json ./
RUN npm ci

# ソースコードが変更されるとこのレイヤーから再ビルド
COPY . .
RUN npm run build

ユースケース

Node.js、Go、Rust、Javaアプリケーション向けの本番グレードのコンテナイメージ構築。最終イメージからビルドツールやソースコードを除外することで、イメージサイズを数百MBから数十MBに削減。

試してみる — Docker CLI Reference

フルツールを開く