📋 このステップで学ぶこと
レイヤーキャッシュの仕組みを深く理解する
.dockerignoreファイルの活用方法
命令の順序を最適化してビルド時間を短縮する
イメージサイズを最小化するテクニック
不要なファイルを削除する正しい方法
実践演習でイメージサイズを大幅に削減する
🔧 0. このステップの前提知識
📚 STEP 11・12の復習
このステップでは、以下の知識を使います。忘れた場合は復習してから進めましょう。
STEP 11 :Dockerfileの基本命令(FROM、RUN、COPY、WORKDIR、CMD)
STEP 11 :レイヤーの基本概念(各命令が1つのレイヤーを作成)
STEP 12 :requirements.txtを先にコピーするパターン
0-1. 作業ディレクトリの準備
# 作業ディレクトリを作成して移動
mkdir -p ~/docker-practice/step13
cd ~/docker-practice/step13
# 現在の場所を確認
pwd
0-2. このステップで得られるスキル
【最適化前と最適化後の違い】
最適化前 最適化後
───────────────────────── ─────────────────────────
イメージサイズ: 1.2GB イメージサイズ: 250MB
初回ビルド: 5分 初回ビルド: 3分
コード変更後の再ビルド: 5分 コード変更後の再ビルド: 10秒
💡 このステップを学ぶと、イメージサイズを80%削減、
再ビルド時間を97%短縮できるようになります!
🎯 1. レイヤーキャッシュの仕組み
1-1. レイヤーキャッシュとは?
Dockerは、イメージをビルドする際に各命令の結果をキャッシュ します。
同じ命令を再度実行する時は、キャッシュを再利用することでビルド時間を大幅に短縮 できます。
📝 例え話:レゴブロックの組み立て
レゴブロックで家を作ることを想像してください。
キャッシュがない場合:
毎回、1階から作り直す必要があります。ちょっと2階の窓を変えたいだけなのに、全部バラして最初からやり直し…
キャッシュがある場合:
1階はそのまま使って、2階だけ作り直せばOK!とても効率的ですね。
Dockerのレイヤーキャッシュも同じ仕組みです。変更がない部分は再利用して、変更があった部分だけ作り直します。
1-2. レイヤーキャッシュの動作を図解
【レイヤーキャッシュの動作】
Dockerfile 1回目のビルド 2回目(app.pyのみ変更)
──────────────────── ────────────── ──────────────────────
① FROM python:3.9-slim → Layer 1 作成 → Layer 1 キャッシュ使用 ✓
② WORKDIR /app → Layer 2 作成 → Layer 2 キャッシュ使用 ✓
③ COPY requirements.txt → Layer 3 作成 → Layer 3 キャッシュ使用 ✓
④ RUN pip install … → Layer 4 作成 → Layer 4 キャッシュ使用 ✓
⑤ COPY . . → Layer 5 作成 → Layer 5 再作成(変更あり)
⑥ CMD [“python”, “app”] → Layer 6 作成 → Layer 6 再作成
【結果】
1回目:5〜10分(全レイヤー作成)
2回目:10秒(⑤⑥だけ再作成)
💡 ポイント:変更があったレイヤー以降は全て再作成される
1-3. 実際のDockerfileで確認
# Dockerfile(キャッシュが効きやすい構造)
FROM python:3.9-slim
# ① ベースイメージ(キャッシュされる)
WORKDIR /app
# ② 作業ディレクトリ設定(キャッシュされる)
COPY requirements.txt .
# ③ requirements.txtをコピー(変更がなければキャッシュ)
RUN pip install -r requirements.txt
# ④ ライブラリをインストール(③がキャッシュされれば、これもキャッシュ)
COPY . .
# ⑤ アプリケーションコードをコピー(変更があれば再実行)
CMD [“python”, “app.py”]
🎯 キャッシュの動作パターン
【app.pyだけ変更した場合】
①〜④はキャッシュを再利用
⑤だけ再実行(10秒)
【requirements.txtを変更した場合】
1-4. キャッシュが無効になるケース
⚠️ キャッシュが使えなくなる条件
Dockerfileの命令を変更した
COPYするファイルの内容が変更された
前の命令でキャッシュが無効になった(それ以降の命令もすべて再実行 )
--no-cacheオプションを使った
# キャッシュを使わずにビルド(問題解決時に使用)
docker build –no-cache -t myapp:latest .
📁 2. .dockerignoreファイルの活用
2-1. .dockerignoreとは?
.dockerignore ファイルは、Dockerのビルド時に無視するファイルやディレクトリ を指定するファイルです。
Gitの.gitignoreと同じような役割です。
【.dockerignoreの効果】
.dockerignoreなし .dockerignoreあり
──────────────────────── ────────────────────────
ビルドコンテキストに送信: ビルドコンテキストに送信:
├── .git/(50MB) ❌ ├── app.py(1KB) ✓
├── node_modules/(200MB)❌ ├── requirements.txt ✓
├── data/(100MB) ❌ └── utils.py(1KB) ✓
├── .env(機密情報) ❌ 危険!
├── tests/(10MB) ❌
├── app.py(1KB) ✓
└── requirements.txt ✓
合計: 360MB 合計: 3KB
ビルド時間: 3分 ビルド時間: 10秒
📝 なぜ必要?
ビルド時間の短縮: 不要なファイルをコピーしない
イメージサイズの削減: 無駄なファイルが含まれない
セキュリティ向上: .envなど秘密情報を含むファイルを除外
キャッシュの効率化: 無関係なファイル変更でキャッシュが無効にならない
2-2. .dockerignoreの書き方
プロジェクトのルートディレクトリ(Dockerfileと同じ場所)に.dockerignoreファイルを作成します。
# .dockerignoreファイルの例
# Gitファイル
.git
.gitignore
.gitattributes
# Python関連
__pycache__
*.pyc
*.pyo
*.pyd
.Python
*.so
*.egg
*.egg-info
dist
build
.venv
venv/
ENV/
# ドキュメント
README.md
docs/
*.md
# テストファイル
tests/
test_*.py
*_test.py
# 開発用ツール
.vscode/
.idea/
*.swp
*.swo
# ログファイル
*.log
logs/
# データファイル(大きいファイル)
*.csv
*.xlsx
data/
# 環境変数ファイル(秘密情報)
.env
.env.local
*.key
*.pem
# OS関連
.DS_Store
Thumbs.db
# Docker関連(Dockerfile自体はCOPYしない)
Dockerfile*
docker-compose*.yml
.dockerignore
2-3. .dockerignoreの実践
# .dockerignoreファイルを作成
cat > .dockerignore << ‘EOF’
.git
__pycache__
*.pyc
.venv
venv/
*.log
.env
tests/
*.md
Dockerfile*
.dockerignore
data/
EOF
# ファイルが作成されたか確認
cat .dockerignore
❌ .dockerignoreなし
問題点:
• 全ファイルがコピーされる
• イメージサイズ:500MB
• ビルド時間:3分
• .gitディレクトリも含まれる
• テストファイルも含まれる
✅ .dockerignoreあり
改善:
• 必要なファイルだけコピー
• イメージサイズ:200MB
• ビルド時間:1分
• クリーンなイメージ
• セキュリティも向上
⚡ 3. 命令の順序最適化
3-1. 最適化の基本原則
💡 キャッシュを最大限活用するルール
変更頻度が低いものを先に、高いものを後に配置する
変更が少ない命令を上に置くことで、キャッシュが有効に使われ、ビルド時間が短縮されます。
【変更頻度による配置順序】
上(先に実行) 変更頻度
─────────────────────────────────────────────
FROM python:3.9-slim ほぼ変更なし
WORKDIR /app ほぼ変更なし
RUN apt-get install … 月に1回程度
COPY requirements.txt . 月に1回程度
RUN pip install … 月に1回程度
COPY config.py . 週に1回程度
COPY app.py . 毎日変更
─────────────────────────────────────────────
下(後で実行)
💡 頻繁に変更されるファイルを下に配置することで、
キャッシュが有効活用される
3-2. 悪い例:非効率な順序
# ❌ 悪い例
FROM python:3.9-slim
WORKDIR /app
# すべてのファイルを先にコピー(変更が多い)
COPY . .
# 依存関係のインストール(変更が少ない)
RUN pip install -r requirements.txt
CMD [“python”, “app.py”]
⚠️ 問題点
アプリケーションコード(app.py)を少し変更しただけで、requirements.txtは変わっていないのに、pip installが毎回実行されてしまいます。
理由: COPY . .でキャッシュが無効になり、それ以降の命令がすべて再実行されるため。
3-3. 良い例:最適化された順序
# ✅ 良い例
FROM python:3.9-slim
WORKDIR /app
# 依存関係ファイルだけ先にコピー(変更が少ない)
COPY requirements.txt .
# 依存関係のインストール(キャッシュされやすい)
RUN pip install -r requirements.txt
# アプリケーションコードは最後(変更が多い)
COPY . .
CMD [“python”, “app.py”]
✅ 改善点
app.pyだけ変更した場合:
• requirements.txtは変更なし → pip installはキャッシュを使う
• 最後のCOPY . .だけ再実行
• ビルド時間:5分 → 10秒に短縮!
3-4. さらに最適化:段階的なコピー
# 🚀 さらに最適化
FROM python:3.9-slim
WORKDIR /app
# ① システムレベルの依存関係(ほとんど変更しない)
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# ② Python依存関係(たまに変更)
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
# ③ 設定ファイル(時々変更)
COPY config.py .
# ④ アプリケーションコード(頻繁に変更)
COPY app.py .
COPY utils.py .
CMD [“python”, “app.py”]
🎯 変更頻度による分類
変更頻度
ファイルの種類
ほぼ変更なし
ベースイメージ、システムパッケージ
たまに変更
requirements.txt、package.json
時々変更
設定ファイル、環境変数
頻繁に変更
アプリケーションコード
📦 4. イメージサイズの最小化テクニック
4-1. なぜサイズを小さくするのか?
📝 小さいイメージのメリット
高速ダウンロード: デプロイが速い
ストレージ節約: Docker Hubの容量制限に優しい
セキュリティ向上: 不要なパッケージがない = 脆弱性が少ない
起動が速い: コンテナの起動時間短縮
4-2. テクニック1:軽量ベースイメージを使う
Pythonベースイメージのサイズ比較
イメージ
サイズ
特徴
python:3.9
約1GB
フル版。開発・デバッグに便利
python:3.9-slim
約150MB
本番環境に推奨
python:3.9-alpine
約50MB
超軽量。一部ライブラリに注意
💡 ベースイメージの選び方
開発環境: 通常版(python:3.9)でOK
本番環境: slimを推奨
最小サイズ優先: alpineを検討(ただし、一部ライブラリが動かないことも)
4-3. テクニック2:複数のRUNをまとめる
# ❌ 悪い例:レイヤーが増える
FROM python:3.9-slim
RUN apt-get update
RUN apt-get install -y gcc
RUN apt-get install -y curl
RUN apt-get install -y vim
# 4つのレイヤーが作られる
# 各レイヤーにキャッシュが残る
# ✅ 良い例:1つのレイヤー
FROM python:3.9-slim
RUN apt-get update && \
apt-get install -y \
gcc \
curl \
vim && \
rm -rf /var/lib/apt/lists/*
# 1つのレイヤーのみ
# キャッシュも削除される
4-4. テクニック3:不要なファイルを削除する
# ✅ ビルド時に不要ファイルを削除
FROM python:3.9-slim
WORKDIR /app
# パッケージインストール後、キャッシュを削除
RUN apt-get update && \
apt-get install -y gcc && \
rm -rf /var/lib/apt/lists/*
# Pythonパッケージインストール後、キャッシュを削除
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
COPY . .
CMD [“python”, “app.py”]
🎯 削除すべきファイル
/var/lib/apt/lists/*:aptのキャッシュ
~/.cache:各種キャッシュファイル
*.pyc:Pythonのコンパイル済みファイル
一時ファイル、ログファイル
4-5. イメージサイズの確認方法
# イメージ一覧とサイズ確認
docker images
# 出力例:
# REPOSITORY TAG IMAGE ID CREATED SIZE
# myapp latest abc123def456 5 minutes ago 200MB
# myapp v1 def456abc789 1 day ago 500MB
# 特定イメージの詳細
docker image inspect myapp:latest
# レイヤーごとのサイズを確認
docker history myapp:latest
🧹 5. 不要なファイルの削除(重要)
5-1. 削除のタイミングが重要
💡 最重要ルール
ファイルは同じRUN命令内で削除する必要があります。
別のRUN命令で削除しても、イメージサイズは減りません!
なぜなら、Dockerのレイヤーは追加のみで、削除は「見えなくなる」だけだからです。
【レイヤーの仕組み】
RUN でファイルを作成 別の RUN で削除
──────────────────── ────────────────────
┌──────────────────┐ ┌──────────────────┐
│ Layer 2 │ │ Layer 3 │
│ bigfile.tar.gz │ │ (削除マーク) │
│ (100MB) │ │ │
└──────────────────┘ └──────────────────┘
↓ ↓
100MB追加 0MB追加
※削除しても
Layer 2は残る!
【結果】イメージサイズ = 100MB + 0MB = 100MB(減らない!)
5-2. 悪い例:削除が効果なし
# ❌ 悪い例
FROM python:3.9-slim
# 大きなファイルをダウンロード(Layer 2: 100MB追加)
RUN curl -o bigfile.tar.gz https://example.com/bigfile.tar.gz
# 展開(Layer 3: 50MB追加)
RUN tar -xzf bigfile.tar.gz
# 削除(Layer 4: 0MB)でもレイヤー2には残ったまま!
RUN rm bigfile.tar.gz
# イメージサイズは減らない(150MB)
5-3. 良い例:同じRUN内で削除
# ✅ 良い例
FROM python:3.9-slim
# ダウンロード→展開→削除を1つのRUNで
RUN curl -o bigfile.tar.gz https://example.com/bigfile.tar.gz && \
tar -xzf bigfile.tar.gz && \
rm bigfile.tar.gz
# この方法ならイメージサイズが小さくなる(50MB)
5-4. 実践例:ビルドツールのインストールと削除
# 開発用ツールをインストール→使用→削除
FROM python:3.9-slim
WORKDIR /app
# ビルドに必要なパッケージをインストール→使用→削除
RUN apt-get update && \
apt-get install -y gcc g++ make && \
# ここで何か処理(例:ライブラリのコンパイル)
pip install numpy && \
# ビルドツールを削除
apt-get purge -y gcc g++ make && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
COPY . .
CMD [“python”, “app.py”]
🎯 削除のベストプラクティス
ダウンロードしたアーカイブは展開後すぐ削除
ビルドツールはビルド完了後すぐ削除
apt-get autoremoveで不要な依存パッケージも削除
pip install --no-cache-dirでキャッシュを残さない
🛠️ 6. 実践演習:イメージサイズの削減
6-1. 演習の目標
実際に最適化前と最適化後のDockerfileを作って、効果を確認しましょう。
📁 演習用のプロジェクト構成
optimization-demo/
├── Dockerfile.before # 最適化前
├── Dockerfile.after # 最適化後
├── requirements.txt
├── app.py
├── utils.py
├── .dockerignore
└── data/
└── sample.csv
6-2. 演習ファイルの作成
# 作業ディレクトリを作成
mkdir -p ~/docker-practice/optimization-demo
cd ~/docker-practice/optimization-demo
# app.py を作成
cat > app.py << ‘EOF’
import pandas as pd
print(“Hello from optimized Docker!”)
print(f”Pandas version: {pd.__version__}”)
EOF
# utils.py を作成
cat > utils.py << ‘EOF’
def helper():
return “Helper function”
EOF
# requirements.txt を作成
cat > requirements.txt << ‘EOF’
pandas==2.0.0
numpy==1.24.2
EOF
# dataディレクトリとサンプルデータを作成
mkdir -p data
echo “id,name,value” > data/sample.csv
echo “1,Alice,100” >> data/sample.csv
6-3. 最適化前のDockerfile
# Dockerfile.before を作成
cat > Dockerfile.before << ‘EOF’
# Dockerfile.before(最適化前)
# 大きいベースイメージ
FROM python:3.9
# すべてのファイルを先にコピー
COPY . /app
WORKDIR /app
# 複数のRUNに分割
RUN apt-get update
RUN apt-get install -y gcc
RUN apt-get install -y curl
RUN pip install -r requirements.txt
CMD [“python”, “app.py”]
EOF
6-4. .dockerignoreファイルを作成
# .dockerignore を作成
cat > .dockerignore << ‘EOF’
__pycache__
*.pyc
.git
.vscode
*.log
data/
tests/
README.md
Dockerfile*
.dockerignore
EOF
6-5. 最適化後のDockerfile
# Dockerfile.after を作成
cat > Dockerfile.after << ‘EOF’
# Dockerfile.after(最適化後)
# 軽量ベースイメージ
FROM python:3.9-slim
WORKDIR /app
# 依存関係ファイルだけ先にコピー
COPY requirements.txt .
# パッケージインストールを1つのRUNにまとめる
RUN apt-get update && \
apt-get install -y –no-install-recommends \
gcc \
curl && \
pip install –no-cache-dir -r requirements.txt && \
# 不要なパッケージを削除
apt-get purge -y gcc && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
# アプリケーションコードは最後
COPY app.py .
COPY utils.py .
CMD [“python”, “app.py”]
EOF
6-6. ビルドして比較
# 最適化前のイメージをビルド
docker build -f Dockerfile.before -t myapp:before .
# 最適化後のイメージをビルド
docker build -f Dockerfile.after -t myapp:after .
# サイズを比較
docker images | grep myapp
# 出力例:
REPOSITORY TAG SIZE
myapp before 1.2GB
myapp after 250MB
# サイズが約5分の1に削減!
6-7. ビルド時間を比較
# app.pyを少し変更
echo ‘print(“Modified!”)’ >> app.py
# 最適化前を再ビルド(全部やり直し)
time docker build -f Dockerfile.before -t myapp:before .
# 結果:約5分
# 最適化後を再ビルド(最後だけ)
time docker build -f Dockerfile.after -t myapp:after .
# 結果:約10秒
✅ 最適化の効果まとめ
項目
最適化前
最適化後
イメージサイズ
1.2GB
250MB(約80%削減)
初回ビルド時間
5分
3分(少し改善)
コード変更後の再ビルド
5分
10秒(97%短縮!)
6-8. 後片付け
# 作成したイメージを削除
docker rmi myapp:before myapp:after
💪 7. 練習問題
練習問題 1
基礎
次のDockerfileの問題点を3つ指摘してください。
FROM python:3.9
COPY . /app
WORKDIR /app
RUN apt-get update
RUN apt-get install -y gcc
RUN pip install -r requirements.txt
CMD [“python”, “app.py”]
解答を見る
【解答】
ベースイメージが大きい: python:3.9ではなくpython:3.9-slimを使うべき
コピーの順序が悪い: 全ファイルを先にコピーしているため、キャッシュが効きにくい。requirements.txtだけ先にコピーすべき
RUNが分割されている: 複数のRUN命令を1つにまとめて、不要なレイヤーを削減すべき
改善例:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN apt-get update && \
apt-get install -y gcc && \
pip install –no-cache-dir -r requirements.txt && \
apt-get purge -y gcc && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
COPY . .
CMD [“python”, “app.py”]
練習問題 2
基礎
.dockerignoreファイルに記述すべき項目を5つ挙げてください。
解答を見る
【解答例】
.git:Gitの履歴ファイル(不要)
__pycache__:Pythonのキャッシュファイル
*.log:ログファイル
.env:環境変数ファイル(秘密情報を含む)
tests/:テストファイル(本番では不要)
他にも、.vscode/、*.md、data/、node_modules/、venv/なども正解です。
練習問題 3
応用
次のDockerfileを最適化してください。イメージサイズとビルド時間の両方を考慮してください。
FROM python:3.9
COPY . /app
WORKDIR /app
RUN apt-get update
RUN apt-get install -y gcc make
RUN pip install numpy pandas
RUN pip install -r requirements.txt
RUN apt-get install -y curl wget
CMD [“python”, “app.py”]
解答を見る
【最適化版】
FROM python:3.9-slim
WORKDIR /app
# requirements.txtだけ先にコピー
COPY requirements.txt .
# 必要なパッケージをまとめてインストール&削除
RUN apt-get update && \
apt-get install -y –no-install-recommends \
gcc \
make \
curl \
wget && \
# Pythonパッケージをインストール
pip install –no-cache-dir numpy pandas && \
pip install –no-cache-dir -r requirements.txt && \
# ビルドツールを削除
apt-get purge -y gcc make && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
# アプリケーションコードは最後
COPY app.py .
COPY utils.py .
CMD [“python”, “app.py”]
最適化のポイント:
python:3.9-slimで軽量化
requirements.txtを先にコピーしてキャッシュ活用
すべてのインストールを1つのRUNにまとめる
ビルドツール(gcc, make)は使用後に削除
--no-cache-dirでpipキャッシュを残さない
不要なaptキャッシュを削除
練習問題 4
応用
次の状況で、ビルド時間を最短にするには、Dockerfileをどう書けばよいでしょうか?
状況:
• app.pyは毎日変更される
• config.pyは週に1回変更される
• requirements.txtは月に1回変更される
解答を見る
【解答】
変更頻度が低いものを上に、高いものを下に配置します。
FROM python:3.9-slim
WORKDIR /app
# ① 月に1回変更:requirements.txt
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
# ② 週に1回変更:config.py
COPY config.py .
# ③ 毎日変更:app.py
COPY app.py .
CMD [“python”, “app.py”]
効果:
app.pyだけ変更した場合:①②はキャッシュ → 超高速
config.pyを変更した場合:①はキャッシュ → 高速
requirements.txtを変更した場合:全部再ビルド → 仕方ない
練習問題 5
発展
次のDockerfileで、イメージサイズが減らない理由を説明してください。
FROM python:3.9-slim
WORKDIR /app
# 大きなファイルをダウンロード
RUN curl -o bigfile.tar.gz https://example.com/bigfile.tar.gz
# 展開
RUN tar -xzf bigfile.tar.gz
# 元のファイルを削除
RUN rm bigfile.tar.gz
CMD [“python”, “app.py”]
解答を見る
【理由】
Dockerのレイヤーは追加のみ で、削除は「見えなくなる」だけです。
別のRUN命令で削除しても、bigfile.tar.gzは2番目のレイヤーに残っているため、イメージサイズは減りません。
正しい方法:
FROM python:3.9-slim
WORKDIR /app
# ダウンロード→展開→削除を1つのRUNで
RUN curl -o bigfile.tar.gz https://example.com/bigfile.tar.gz && \
tar -xzf bigfile.tar.gz && \
rm bigfile.tar.gz
CMD [“python”, “app.py”]
この方法なら、最終的なレイヤーには展開後のファイルだけが含まれ、bigfile.tar.gzは残りません。
練習問題 6
応用
イメージサイズを確認するコマンドと、レイヤーごとのサイズを確認するコマンドをそれぞれ書いてください。
解答を見る
【解答】
1. イメージサイズの確認:
docker images
# または特定のイメージのみ
docker images myapp
# サイズでソート
docker images –format “table {{.Repository}}\t{{.Tag}}\t{{.Size}}” | sort -k3 -h
2. レイヤーごとのサイズ確認:
docker history myapp:latest
# 省略なしで表示
docker history myapp:latest –no-trunc
3. 詳細情報:
docker image inspect myapp:latest
練習問題 7
発展
データサイエンス用のDockerfileを最適化してください。numpy、pandas、scikit-learnを含め、できるだけ小さくしてください。
解答を見る
【最適化版】
FROM python:3.9-slim
WORKDIR /app
# requirements.txtの内容
# numpy==1.21.0
# pandas==1.3.0
# scikit-learn==0.24.2
COPY requirements.txt .
# ビルドに必要なパッケージをインストール→使用→削除
RUN apt-get update && \
apt-get install -y –no-install-recommends \
gcc \
g++ \
gfortran \
libopenblas-dev \
liblapack-dev && \
# Pythonパッケージをインストール
pip install –no-cache-dir -r requirements.txt && \
# ビルドツールを削除
apt-get purge -y \
gcc \
g++ \
gfortran && \
apt-get autoremove -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
# Pythonキャッシュも削除
find /usr/local/lib/python3.9 -type d -name __pycache__ -exec rm -r {} + 2>/dev/null || true
# アプリケーションコード
COPY app.py .
CMD [“python”, “app.py”]
ポイント:
slimベースで軽量化
ビルドツール(gcc, g++など)は使用後に削除
実行時に必要なlibopenblasなどは残す
__pycache__も削除
すべて1つのRUNで実行
サイズ比較:
最適化前:約1.5GB
最適化後:約600MB(60%削減)
練習問題 8
発展
次の要件を満たすDockerfileを作成してください。
ベースイメージ:python:3.9-slim
必要なパッケージ:Flask、requests
アプリケーションファイル:app.py、config.py、templates/ディレクトリ
ポート5000を公開
イメージサイズとビルド時間を最適化すること
解答を見る
【最適化版Dockerfile】
FROM python:3.9-slim
WORKDIR /app
# ポートを公開
EXPOSE 5000
# 環境変数の設定
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
# requirements.txtを先にコピー
COPY requirements.txt .
# 依存関係をインストール
RUN pip install –no-cache-dir -r requirements.txt
# 設定ファイル(変更頻度:低)
COPY config.py .
# テンプレートディレクトリ(変更頻度:中)
COPY templates/ templates/
# アプリケーションコード(変更頻度:高)
COPY app.py .
# 非rootユーザーで実行(セキュリティ向上)
RUN useradd -m appuser && \
chown -R appuser:appuser /app
USER appuser
CMD [“flask”, “run”, “–host=0.0.0.0”]
requirements.txt:
Flask==2.0.1
requests==2.26.0
.dockerignore:
__pycache__
*.pyc
.git
.vscode
*.log
.env
tests/
*.md
最適化のポイント:
変更頻度順にファイルをコピー(キャッシュ活用)
--no-cache-dirでpipキャッシュを残さない
.dockerignoreで不要ファイルを除外
非rootユーザーで実行(セキュリティ向上)
環境変数を明示的に設定
📝 STEP 13 のまとめ
✅ このステップで学んだこと
レイヤーキャッシュ: 変更がない命令はキャッシュを再利用してビルドを高速化
.dockerignore: 不要なファイルを除外してサイズとビルド時間を削減
命令の順序: 変更頻度が低いものを上に配置してキャッシュを最大活用
イメージサイズ削減: 軽量ベースイメージ、RUNのまとめ、不要ファイル削除
削除のタイミング: 同じRUN内で削除しないとサイズは減らない
📊 最適化テクニック一覧
テクニック
効果
実装方法
軽量ベースイメージ
サイズ80%削減
python:3.9-slimを使用
命令の順序最適化
再ビルド97%高速化
変更頻度が低いものを先に
.dockerignore
ビルド時間短縮
不要ファイルを除外
RUNをまとめる
レイヤー数削減
&&で連結
キャッシュ削除
サイズ削減
--no-cache-dir、rm -rf
💡 重要ポイント
最適化により、イメージサイズを50〜80%削減 できる
ビルド時間を数分から数秒 に短縮できる
小さいイメージは、デプロイが速く、セキュリティも向上する
最適化は開発初期から意識することが大切
🎯 次のステップの予告
次のSTEP 14では、「マルチステージビルド」 を学びます。
ビルド用と実行用のイメージを分離
さらに小さいイメージを作成
セキュリティの向上
実践例:Pythonアプリの最適化
究極に小さく、セキュアなイメージを作りましょう!