Lab 5: Docker Compose

このラボでは、Docker Composeを使って複数コンテナを一括管理する方法を学びます。Lab 4で手動で行ったネットワークの作成やコンテナの起動を、YAMLファイル1つで定義できます。

1. docker-compose.yml の基本構文

Docker Composeの設定ファイルはYAML形式で記述します。主な項目は以下の通りです:

項目説明
servicesコンテナ(サービス)の定義
buildDockerfileからビルドする場合のパス
image既存イメージを使用する場合
portsポートマッピング
volumesボリュームマウント
networks接続するネットワーク
depends_onサービスの起動順序
environment環境変数
restart再起動ポリシー

2. サンプル: Flaskアプリの docker-compose.yml

Lab 2で作成したFlaskアプリをDocker Composeで起動してみましょう。

mkdir -p ~/compose-demo
cd ~/compose-demo

まず app.py と requirements.txt、Dockerfile を作成します(Lab 2と同じ内容)。

cat << 'EOF' > app.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return '<h1>Hello, Docker Lab!</h1><p>おめでとうございます!Flaskアプリがコンテナで動いています。</p>'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
EOF

cat << 'EOF' > requirements.txt
flask
EOF

cat << 'EOF' > Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
EOF

docker-compose.yml を作成

cat << 'EOF' > docker-compose.yml
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - ./app.py:/app/app.py
    restart: unless-stopped
EOF
💡 解説:
build: . — カレントディレクトリのDockerfileでビルド
ports — ホスト:コンテナのポートマッピング
volumes — app.pyをバインドマウント(コード変更が即反映)
restart: unless-stopped — 手動停止以外では自動再起動

3. Docker Compose の基本コマンド

# サービスをビルドして起動(バックグラウンド)
docker compose up -d

# 実行中のサービスを確認
docker compose ps

# ログを表示
docker compose logs

# リアルタイムでログを追跡
docker compose logs -f

# サービスを停止して削除
docker compose down
💡 ヒント:
docker compose up --build — イメージを再ビルドして起動
docker compose down -v — ボリュームも一緒に削除
docker compose exec web /bin/bash — サービスのコンテナに入る

4. スケールアップ

Composeを使うと、同じサービスを複数インスタンス起動できます。

⚠️ 注意: スケールアップする場合、ポートの競合を避けるために ports の指定を変更する必要があります。
# docker-compose.yml のportsを範囲指定に変更
cat << 'EOF' > docker-compose.yml
services:
  web:
    build: .
    ports:
      - "5000-5002:5000"
    volumes:
      - ./app.py:/app/app.py
    restart: unless-stopped
EOF

# 3インスタンス起動
docker compose up -d --scale web=3

# 確認
docker compose ps

# 停止
docker compose down

5. 📝 練習問題: Flask + Redis の複数コンテナ構成

課題: Lab 4で手動で構築したFlask + Redis構成を、Docker Composeで定義しましょう。
  1. Redis対応のapp.pyを作成
  2. docker-compose.ymlにflaskとredisの2サービスを定義
  3. docker compose up -d で起動
  4. ブラウザで動作確認
  5. docker compose down で停止

解答例

mkdir -p ~/compose-redis
cd ~/compose-redis

# Redis対応の app.py
cat << 'EOF' > app.py
from flask import Flask
import redis

app = Flask(__name__)
r = redis.Redis(host='redis', port=6379, decode_responses=True)

@app.route('/')
def hello():
    count = r.incr('hits')
    return f'<h1>Docker Compose デモ</h1><p>このページは {count} 回アクセスされました。</p>'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
EOF

# requirements.txt
cat << 'EOF' > requirements.txt
flask
redis
EOF

# Dockerfile
cat << 'EOF' > Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
EOF

# docker-compose.yml
cat << 'EOF' > docker-compose.yml
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - ./app.py:/app/app.py
    depends_on:
      - redis
    restart: unless-stopped

  redis:
    image: redis:7
    restart: unless-stopped
EOF
# 起動
docker compose up -d

# 状態確認
docker compose ps

# ログ確認
docker compose logs

# ブラウザで http://localhost:5000 にアクセス
# リロードするたびにカウンターが増える

# 停止・削除
docker compose down
💡 ポイント:
depends_on: - redis でRedisが先に起動する
・Composeが自動でネットワークを作成するため、host='redis' でサービス名によるDNS解決ができる
docker compose down でネットワークも含めてすべて片付く

← 前のラボ | 🏠 トップに戻る