📋 このステップで学ぶこと
- マルチステージビルドとは何か
- ビルド用と実行用のステージを分離する方法
- イメージサイズを劇的に削減するテクニック
- セキュリティを向上させる方法
- 実践例:Pythonアプリの最適化
- 実践演習でマルチステージビルドを実装
🔧 0. このステップの前提知識
📚 STEP 13の復習
このステップでは、以下の知識を使います。忘れた場合は復習してから進めましょう。
- STEP 13:レイヤーキャッシュの仕組み(各命令が1つのレイヤーを作成)
- STEP 13:イメージサイズを削減するテクニック(軽量ベースイメージ、RUNをまとめる)
- STEP 13:同じRUN内で削除しないとサイズは減らない
0-1. 作業ディレクトリの準備
# 作業ディレクトリを作成して移動
mkdir -p ~/docker-practice/step14
cd ~/docker-practice/step14
# 現在の場所を確認
pwd
0-2. このステップで得られるスキル
【マルチステージビルドの効果】
シングルステージ マルチステージ
───────────────────────── ─────────────────────────
イメージサイズ: 1.5GB イメージサイズ: 200MB
含まれるパッケージ: 500+ 含まれるパッケージ: 100
ビルドツール: gcc, g++, make ビルドツール: なし
セキュリティリスク: 高 セキュリティリスク: 低
💡 このステップを学ぶと、イメージサイズを80〜90%削減、
セキュリティを大幅に向上できるようになります!
🎯 1. マルチステージビルドとは?
1-1. 基本概念
マルチステージビルドとは、1つのDockerfileの中で複数のステージ(段階)を定義し、
各ステージを独立して実行できる機能です。
📝 例え話:料理の準備と提供
レストランで料理を作ることを想像してください。
【キッチン(ビルドステージ)】
• 野菜を切る包丁
• 調理器具がたくさん
• 材料の袋やパッケージ
• 作業台が散らかっている
【お客様のテーブル(実行ステージ)】
• 完成した料理だけ
• きれいなお皿
• 包丁や材料のゴミはない
• すっきり!
マルチステージビルドも同じで、「作る場所」と「使う場所」を分けることで、最終的なイメージに不要なものを含めません。
1-2. マルチステージビルドの仕組み
【マルチステージビルドの流れ】
┌─────────────────────────────────────────────────────────────┐
│ ステージ1: ビルドステージ(builder) │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
│ FROM python:3.9 AS builder │
│ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ • gcc, g++, make などのビルドツール ││
│ │ • numpy, pandas のソースコード ││
│ │ • コンパイル中の一時ファイル ││
│ │ • ビルド済みパッケージ ✓ ││
│ └─────────────────────────────────────────────────────────┘│
│ │ │
│ │ 必要なものだけコピー │
│ ▼ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ ステージ2: 実行ステージ(最終イメージ) │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
│ FROM python:3.9-slim │
│ COPY –from=builder /root/.local /root/.local │
│ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ • ビルド済みパッケージのみ ✓ ││
│ │ • アプリケーションコード ││
│ │ • ビルドツールは含まれない ✓ ││
│ │ • 中間ファイルも含まれない ✓ ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
【結果】
ビルドステージ: 1.5GB(破棄される)
実行ステージ: 200MB ← これが最終イメージ
1-3. なぜマルチステージビルドが必要?
💡 マルチステージビルドの利点
- イメージサイズの劇的な削減:ビルドツールを含めない → 50〜90%削減
- セキュリティ向上:不要なツールがない → 攻撃面が減る
- クリーンな最終イメージ:実行に必要なものだけ
- Dockerfileが1つ:管理が楽
1-4. シングルステージ vs マルチステージ
❌ シングルステージ
問題点:
• ビルドツールも含まれる
• イメージサイズ:1.5GB
• 中間ファイルも残る
• セキュリティリスク高
• 不要なファイルだらけ
✅ マルチステージ
改善:
• 実行ファイルだけコピー
• イメージサイズ:200MB
• クリーンな構成
• セキュリティリスク低
• 必要なものだけ
🏗️ 2. ビルド用と実行用の分離
2-1. 基本的な構造
マルチステージビルドでは、複数のFROM命令を使って、ステージを分離します。
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ1: ビルドステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS builder
WORKDIR /app
# ビルドに必要なツールをインストール
RUN apt-get update && apt-get install -y gcc g++ make
# 依存関係をインストール
COPY requirements.txt .
RUN pip install –user -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ2: 実行ステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9-slim
WORKDIR /app
# ステージ1からビルド済みパッケージだけコピー
COPY –from=builder /root/.local /root/.local
# アプリケーションコードをコピー
COPY app.py .
# PATHを設定
ENV PATH=/root/.local/bin:$PATH
CMD [“python”, “app.py”]
2-2. キーポイントの解説
【マルチステージビルドの重要な構文】
FROM python:3.9 AS builder
──────────
│
└─ ステージに名前を付ける
この名前で後から参照できる
COPY –from=builder /root/.local /root/.local
──────────────
│
└─ 前のステージからファイルをコピー
builder ステージの /root/.local を
現在のステージにコピー
【ポイント】
• 最後の FROM が最終イメージになる
• 中間ステージは破棄される
• 名前を付けないと FROM 0、FROM 1 で参照(非推奨)
2-3. 各ステージの役割
| ステージ |
役割 |
| ビルドステージ(builder) |
ソースコードのコンパイル、依存関係のビルド、静的ファイルの生成、テストの実行 |
| 実行ステージ(最終) |
ビルド済みファイルだけ受け取る、実行に必要な最小限の環境、アプリケーションの実行 |
2-4. pip install –user の意味
📝 –user オプションとは?
pip install --userは、パッケージをユーザーディレクトリ(/root/.local)にインストールします。
なぜ使うのか?
• システム全体にインストールすると、Python本体のディレクトリにパッケージが混ざる
• --userを使うと、/root/.localにまとまる
• まとまった場所をCOPY --fromでコピーしやすい
📦 3. イメージサイズの大幅削減
3-1. 実例:シングルステージ vs マルチステージ
実際の数字で比較してみましょう。
【例1】シングルステージ(最適化なし)
# シングルステージ
FROM python:3.9
WORKDIR /app
# ビルドツールをインストール
RUN apt-get update && \
apt-get install -y gcc g++ make
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD [“python”, “app.py”]
# イメージサイズを確認
$ docker images myapp:single
REPOSITORY TAG SIZE
myapp single 1.5GB
【例2】マルチステージ
# マルチステージ
FROM python:3.9 AS builder
WORKDIR /app
RUN apt-get update && \
apt-get install -y gcc g++ make
COPY requirements.txt .
RUN pip install –user -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━
# 実行ステージ
FROM python:3.9-slim
WORKDIR /app
COPY –from=builder /root/.local /root/.local
COPY app.py .
ENV PATH=/root/.local/bin:$PATH
CMD [“python”, “app.py”]
# イメージサイズを確認
$ docker images myapp:multi
REPOSITORY TAG SIZE
myapp multi 250MB
# 削減率:約83%!
3-2. なぜこんなに小さくなる?
💡 サイズ削減の理由
- ビルドツール不要:gcc、g++、makeなどは実行ステージに含まれない
- 軽量ベースイメージ:実行ステージは
python:3.9-slim
- 中間ファイル不要:ビルドキャッシュなどは破棄される
- 必要なものだけ:ビルド済みパッケージだけコピー
サイズ削減の内訳
| 項目 |
シングルステージ |
マルチステージ |
| ベースイメージ |
python:3.9(約900MB) |
python:3.9-slim(約150MB) |
| ビルドツール |
gcc, g++, make(約300MB) |
なし(0MB) |
| Pythonパッケージ |
約300MB |
約100MB(必要なもののみ) |
| 合計 |
約1.5GB |
約250MB |
🔒 4. セキュリティの向上
4-1. マルチステージビルドのセキュリティメリット
🔐 セキュリティが向上する理由
- 攻撃面の縮小:ビルドツールがない = 悪用できるツールが少ない
- 脆弱性の削減:パッケージ数が少ない = セキュリティリスク低下
- クリーンな環境:不要なファイルがない = 情報漏洩リスク低下
4-2. 含まれるパッケージ数の比較
❌ シングルステージ
含まれるパッケージ:
• gcc, g++, make
• build-essential
• curl, wget
• git
• その他開発ツール
合計:約500パッケージ
✅ マルチステージ
含まれるパッケージ:
• Python本体
• 必要なライブラリのみ
• 実行時依存関係のみ
合計:約100パッケージ
4-3. セキュリティベストプラクティス
💡 セキュリティベストプラクティス
- ビルドツールは実行ステージに含めない
- 実行ステージは軽量ベースイメージを使う
- 非rootユーザーで実行する
- 定期的にイメージの脆弱性スキャンを実行
# 非rootユーザーで実行する例
FROM python:3.9-slim
WORKDIR /app
COPY –from=builder /root/.local /root/.local
COPY app.py .
ENV PATH=/root/.local/bin:$PATH
# 非rootユーザーを作成して切り替え
RUN useradd -m appuser && \
chown -R appuser:appuser /app
USER appuser
CMD [“python”, “app.py”]
🐍 5. 実践例:Pythonアプリの最適化
5-1. numpy/pandasを使うアプリ
データ分析用のライブラリは、ビルドに時間がかかります。
マルチステージビルドで最適化しましょう。
# Dockerfile(マルチステージ)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ビルドステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS builder
WORKDIR /app
# ビルドに必要なパッケージ
RUN apt-get update && \
apt-get install -y –no-install-recommends \
gcc \
g++ \
gfortran \
libopenblas-dev \
liblapack-dev && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
# ユーザーディレクトリにインストール
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# 実行ステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9-slim
WORKDIR /app
# 実行に必要な依存関係のみ
RUN apt-get update && \
apt-get install -y –no-install-recommends \
libopenblas-base \
libgomp1 && \
rm -rf /var/lib/apt/lists/*
# ビルドステージからパッケージをコピー
COPY –from=builder /root/.local /root/.local
# アプリケーションコード
COPY app.py .
COPY data_processor.py .
# PATHを設定
ENV PATH=/root/.local/bin:$PATH
# 非rootユーザーで実行
RUN useradd -m appuser && \
chown -R appuser:appuser /app
USER appuser
CMD [“python”, “app.py”]
🎯 最適化のポイント
- ビルドステージ:gcc、g++などでnumpy/pandasをビルド
- 実行ステージ:ビルドツールは不要、実行時依存だけインストール
- サイズ削減:1.5GB → 600MB(60%削減)
- セキュリティ:非rootユーザーで実行
5-2. Flaskアプリケーション
# Dockerfile(Flask + gunicorn)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ビルドステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS builder
WORKDIR /app
COPY requirements.txt .
# 依存関係をビルド
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# 実行ステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9-slim
WORKDIR /app
# ビルド済みパッケージをコピー
COPY –from=builder /root/.local /root/.local
# アプリケーションコード
COPY app.py .
COPY config.py .
COPY templates/ templates/
COPY static/ static/
# PATHを設定
ENV PATH=/root/.local/bin:$PATH
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
# 非rootユーザー
RUN useradd -m flaskuser && \
chown -R flaskuser:flaskuser /app
USER flaskuser
EXPOSE 5000
CMD [“gunicorn”, “–bind”, “0.0.0.0:5000”, “app:app”]
🛠️ 6. 実践演習
6-1. 演習の目標
実際にマルチステージビルドを実装して、シングルステージと比較してみましょう。
📁 プロジェクト構成
multistage-demo/
├── Dockerfile.single # シングルステージ(比較用)
├── Dockerfile.multi # マルチステージ
├── requirements.txt
├── app.py
└── data_processor.py
6-2. 演習ファイルの作成
# 作業ディレクトリを作成
mkdir -p ~/docker-practice/multistage-demo
cd ~/docker-practice/multistage-demo
# requirements.txt を作成
cat > requirements.txt << ‘EOF’
numpy==1.21.0
pandas==1.3.0
requests==2.26.0
EOF
# app.py を作成
cat > app.py << ‘EOF’
import pandas as pd
import numpy as np
from data_processor import process_data
def main():
print(“データ処理を開始します…”)
# データの読み込み
data = pd.DataFrame({
‘name’: [‘Alice’, ‘Bob’, ‘Charlie’],
‘score’: [85, 90, 78]
})
# データ処理
result = process_data(data)
print(“処理結果:”)
print(result)
print(“\nデータ処理が完了しました!”)
if __name__ == “__main__”:
main()
EOF
# data_processor.py を作成
cat > data_processor.py << ‘EOF’
import pandas as pd
import numpy as np
def process_data(df):
“””データ処理関数”””
# 平均を計算
df[‘average’] = df[‘score’].mean()
# ランクを追加
df[‘rank’] = df[‘score’].rank(ascending=False)
return df
EOF
6-3. シングルステージDockerfileを作成
# Dockerfile.single を作成
cat > Dockerfile.single << ‘EOF’
# シングルステージ(比較用)
FROM python:3.9
WORKDIR /app
# ビルドツールをインストール
RUN apt-get update && \
apt-get install -y gcc g++ gfortran && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
COPY . .
CMD [“python”, “app.py”]
EOF
6-4. マルチステージDockerfileを作成
# Dockerfile.multi を作成
cat > Dockerfile.multi << ‘EOF’
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ビルドステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS builder
WORKDIR /app
# ビルドに必要なパッケージ
RUN apt-get update && \
apt-get install -y –no-install-recommends \
gcc \
g++ \
gfortran && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
# ユーザーディレクトリにインストール
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# 実行ステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9-slim
WORKDIR /app
# ビルドステージからパッケージをコピー
COPY –from=builder /root/.local /root/.local
# アプリケーションコード
COPY app.py .
COPY data_processor.py .
# PATHを設定
ENV PATH=/root/.local/bin:$PATH
CMD [“python”, “app.py”]
EOF
6-5. ビルドして比較
# シングルステージをビルド
docker build -f Dockerfile.single -t dataapp:single .
# マルチステージをビルド
docker build -f Dockerfile.multi -t dataapp:multi .
# サイズを比較
docker images | grep dataapp
REPOSITORY TAG IMAGE ID CREATED SIZE
dataapp single abc123def456 2 minutes ago 1.2GB
dataapp multi def456abc789 1 minute ago 300MB
# マルチステージは約75%削減!
6-6. 両方を実行して動作確認
# シングルステージを実行
docker run –rm dataapp:single
# マルチステージを実行
docker run –rm dataapp:multi
データ処理を開始します…
処理結果:
name score average rank
0 Alice 85 84.3 2.0
1 Bob 90 84.3 1.0
2 Charlie 78 84.3 3.0
データ処理が完了しました!
6-7. 後片付け
# 作成したイメージを削除
docker rmi dataapp:single dataapp:multi
✅ 演習のまとめ
- 両方のイメージが同じように動作する
- マルチステージは約75%小さい
- ビルドツールは最終イメージに含まれない
- セキュリティも向上している
🚀 7. 高度なテクニック
7-1. 複数のビルドステージ
3つ以上のステージを使うこともできます。
# 複数ステージの例
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ1: テストステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS tester
WORKDIR /app
COPY requirements.txt requirements-dev.txt ./
RUN pip install -r requirements.txt -r requirements-dev.txt
COPY . .
# テストを実行(失敗したらビルドが止まる)
RUN pytest tests/
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ2: ビルドステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS builder
WORKDIR /app
RUN apt-get update && \
apt-get install -y gcc g++ && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ3: 実行ステージ
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9-slim
WORKDIR /app
COPY –from=builder /root/.local /root/.local
COPY app.py .
ENV PATH=/root/.local/bin:$PATH
CMD [“python”, “app.py”]
7-2. 特定のステージだけビルド
# テストステージだけビルド(本番イメージは作らない)
docker build –target tester -t myapp:test .
# ビルドステージまでビルド(デバッグ用)
docker build –target builder -t myapp:builder .
# 最終ステージまでビルド(通常)
docker build -t myapp:latest .
📝 –target オプションの活用
- テスト実行:
--target testerでテストだけ実行
- デバッグ:
--target builderでビルド環境を確認
- CI/CD:テストステージをCI、最終ステージをCDで使い分け
💪 8. 練習問題
練習問題 1
基礎
マルチステージビルドの利点を3つ挙げてください。
【解答例】
- イメージサイズの削減:ビルドツールや中間ファイルを含めないため、最終イメージが50〜90%小さくなる
- セキュリティの向上:不要なパッケージやツールがないため、攻撃面が縮小し、脆弱性のリスクが減る
- クリーンな構成:実行に必要なものだけが含まれるため、イメージがシンプルで管理しやすい
練習問題 2
基礎
次のDockerfileで、COPY --from=builderは何をしていますか?
FROM python:3.9 AS builder
RUN pip install –user numpy
FROM python:3.9-slim
COPY –from=builder /root/.local /root/.local
【解答】
COPY --from=builderは、builderステージからファイルをコピーしています。
具体的には:
• builderステージでインストールされたnumpyパッケージ
• /root/.localディレクトリ全体を、実行ステージの同じパスにコピー
これにより、ビルドツール(gcc等)は含めずに、ビルド済みパッケージだけを実行ステージに持ってくることができます。
練習問題 3
応用
次のシングルステージDockerfileをマルチステージに書き換えてください。
FROM python:3.9
WORKDIR /app
RUN apt-get update && \
apt-get install -y gcc g++
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD [“python”, “app.py”]
【マルチステージ版】
# ビルドステージ
FROM python:3.9 AS builder
WORKDIR /app
RUN apt-get update && \
apt-get install -y gcc g++ && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# 実行ステージ
FROM python:3.9-slim
WORKDIR /app
# ビルド済みパッケージをコピー
COPY –from=builder /root/.local /root/.local
# アプリケーションコード
COPY app.py .
# PATHを設定
ENV PATH=/root/.local/bin:$PATH
CMD [“python”, “app.py”]
練習問題 4
応用
Flask + gunicornのアプリケーション用マルチステージDockerfileを作成してください。
要件:
• requirements.txt: Flask, gunicorn
• アプリケーション: app.py, config.py, templates/
• 非rootユーザーで実行
• イメージサイズを最小化
【解答】
# ビルドステージ
FROM python:3.9 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# 実行ステージ
FROM python:3.9-slim
WORKDIR /app
# ビルド済みパッケージをコピー
COPY –from=builder /root/.local /root/.local
# アプリケーションファイル
COPY app.py .
COPY config.py .
COPY templates/ templates/
# 環境変数
ENV PATH=/root/.local/bin:$PATH
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
# 非rootユーザー
RUN useradd -m flaskuser && \
chown -R flaskuser:flaskuser /app
USER flaskuser
EXPOSE 5000
CMD [“gunicorn”, “–bind”, “0.0.0.0:5000”, “app:app”]
練習問題 5
発展
次の要件を満たすマルチステージDockerfileを作成してください。
- ステージ1:テストを実行(pytest)
- ステージ2:依存関係をビルド
- ステージ3:実行環境(最小構成)
- テストが失敗したらビルドを中止
【解答】
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ1: テスト
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS tester
WORKDIR /app
# テスト用の依存関係
COPY requirements.txt requirements-dev.txt ./
RUN pip install –no-cache-dir -r requirements.txt -r requirements-dev.txt
# テストコード
COPY tests/ tests/
COPY app.py .
COPY data_processor.py .
# テストを実行(失敗したらここでビルドが止まる)
RUN pytest tests/ -v
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ2: ビルド
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9 AS builder
WORKDIR /app
RUN apt-get update && \
apt-get install -y –no-install-recommends \
gcc \
g++ && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# ステージ3: 実行
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
FROM python:3.9-slim
WORKDIR /app
# ビルド済みパッケージをコピー
COPY –from=builder /root/.local /root/.local
# アプリケーションコード
COPY app.py .
COPY data_processor.py .
ENV PATH=/root/.local/bin:$PATH
# 非rootユーザー
RUN useradd -m appuser && \
chown -R appuser:appuser /app
USER appuser
CMD [“python”, “app.py”]
ビルド方法:
# 通常のビルド(全ステージ実行、テスト含む)
docker build -t myapp:latest .
# テストステージだけ実行(デバッグ用)
docker build –target tester -t myapp:test .
練習問題 6
応用
マルチステージビルドで、イメージサイズが1.5GB→300MBになりました。削減率は何%ですか?
【解答】
削減率の計算式:
(元のサイズ - 新しいサイズ) ÷ 元のサイズ × 100
(1.5GB – 300MB) ÷ 1.5GB × 100
= (1500MB – 300MB) ÷ 1500MB × 100
= 1200MB ÷ 1500MB × 100
= 0.8 × 100
= 80%
答え:80%削減
元のサイズの20%まで小さくなったということです。
練習問題 7
発展
–target オプションの使い方と用途を説明してください。
【解答】
–target オプションとは:
マルチステージビルドで、特定のステージまでビルドするオプションです。
# 構文
docker build –target ステージ名 -t イメージ名 .
用途:
- テスト実行:
--target testerでテストステージだけ実行し、テストが通るか確認
- デバッグ:
--target builderでビルド環境に入り、問題を調査
- CI/CD:CIではテストステージ、CDでは最終ステージを使い分け
- 開発効率化:必要なステージだけビルドして時間を節約
# 例:テストステージだけ実行
docker build –target tester -t myapp:test .
# 例:ビルドステージまで実行(デバッグ用)
docker build –target builder -t myapp:debug .
docker run -it myapp:debug bash
練習問題 8
発展
scikit-learnを使うデータサイエンスアプリのマルチステージDockerfileを作成してください。実行時に必要なライブラリ(libopenblas等)も考慮すること。
【解答】
# ビルドステージ
FROM python:3.9 AS builder
WORKDIR /app
# ビルドに必要なツール
RUN apt-get update && \
apt-get install -y –no-install-recommends \
gcc \
g++ \
gfortran \
libopenblas-dev \
liblapack-dev && \
rm -rf /var/lib/apt/lists/*
# requirements.txt
# numpy==1.21.0
# pandas==1.3.0
# scikit-learn==0.24.2
COPY requirements.txt .
RUN pip install –user –no-cache-dir -r requirements.txt
# ━━━━━━━━━━━━━━━━━━━━━━━━━━
# 実行ステージ
FROM python:3.9-slim
WORKDIR /app
# 実行時に必要な依存関係(重要!)
RUN apt-get update && \
apt-get install -y –no-install-recommends \
libopenblas-base \
libgomp1 && \
rm -rf /var/lib/apt/lists/*
# ビルド済みパッケージ
COPY –from=builder /root/.local /root/.local
# アプリケーションコード
COPY *.py ./
ENV PATH=/root/.local/bin:$PATH
RUN useradd -m dsuser && \
chown -R dsuser:dsuser /app
USER dsuser
CMD [“python”, “train.py”]
ポイント:
- libopenblas-base:numpy/scikit-learnの実行に必要
- libgomp1:OpenMPの実行時ライブラリ(並列処理に必要)
- ビルドツール(gcc等)は実行ステージに含まれない
- サイズ:約1.5GB → 約600MB(60%削減)
📝 STEP 14 のまとめ
✅ このステップで学んだこと
- マルチステージビルド:ビルド用と実行用のステージを分離
- FROM … AS name:ステージに名前を付ける
- COPY –from=:前のステージからファイルをコピー
- イメージサイズ削減:ビルドツールを含めないことで50〜90%削減
- セキュリティ向上:不要なパッケージがない = 脆弱性が少ない
- –target:特定のステージだけビルド
📊 マルチステージビルドのパターン
| パターン |
ビルドステージ |
実行ステージ |
| Pythonアプリ |
python:3.9 + gcc |
python:3.9-slim |
| データサイエンス |
python:3.9 + gcc/gfortran |
python:3.9-slim + libopenblas |
| Node.js(フロント) |
node:16(npm build) |
nginx:alpine(静的配信) |
| Go言語 |
golang:1.17(コンパイル) |
scratch / alpine(バイナリのみ) |
💡 重要ポイント
- マルチステージビルドは本番環境では必須のテクニック
- イメージサイズを劇的に削減できる(80〜90%も可能)
- セキュリティとパフォーマンスが大幅に向上する
- Dockerfileが1つで管理できるため、メンテナンスが楽
🎯 次のステップの予告
次のSTEP 15では、「Docker Composeとは」を学びます。
- 複数のコンテナを簡単に管理
- docker-compose.ymlの基本構造
- サービスの定義と起動
- PostgreSQL、Airflow、Sparkなどを連携
複数コンテナの世界へ踏み出しましょう!