STEP 27:プロジェクト③ 本番環境デプロイシミュレーション

🚀 STEP 27: プロジェクト③ 本番環境デプロイシミュレーション

開発環境から本番環境へ – プロダクションレディなシステム構築

📋 このプロジェクトのゴール

  • 開発環境と本番環境の設定分離
  • Docker Secretsによるシークレット管理
  • イメージのタグ管理とバージョニング
  • ログ集約とログローテーション
  • リソース制限とパフォーマンスチューニング
  • バックアップ・リストア手順の確立
  • 本番デプロイのチェックリスト作成

目標:本番環境で安定稼働するシステムの構築と運用手順の確立

学習時間の目安: 3時間

🔧 0. このプロジェクトの前提知識

📚 これまでの学習の復習
  • Docker Compose:マルチコンテナ構成(STEP 15-18)
  • 環境変数:.envファイル管理(STEP 21)
  • リソース制限:メモリ、CPU制限(STEP 24)
  • ETLパイプライン:STEP 25-26のプロジェクト
  • ヘルスチェック:コンテナ監視(STEP 24)

0-1. 作業ディレクトリの準備

mkdir -p ~/docker-practice/step27 cd ~/docker-practice/step27 pwd

0-2. 本番環境のアーキテクチャ

【本番環境デプロイ アーキテクチャ】 ┌─────────────────────────────────────────────────────────────────────┐ │ 本番環境システム構成 │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Docker Compose │ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ PostgreSQL │◄────────────│ ETL │ │ │ │ │ │ :5432 │ DB接続 │ Pipeline │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ │ │ │ ↓ ↓ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ Volume │ │ Logs │ │ │ │ │ │ (永続化) │ │ (ファイル) │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ 【セキュリティ】 【運用】 │ │ ├── Docker Secrets ├── 自動再起動(restart: always) │ │ ├── 非rootユーザー ├── ヘルスチェック │ │ └── 読み取り専用マウント ├── ログローテーション │ │ └── バックアップ/リストア │ │ │ └─────────────────────────────────────────────────────────────────────┘

0-3. 開発環境と本番環境の違い

項目開発環境本番環境
デバッグ有効(DEBUG=true)無効(DEBUG=false)
ログレベルDEBUGWARNING
リソース制限なし厳密に設定
再起動ポリシーnoalways
パスワード管理.envファイルDocker Secrets
データ永続化任意必須
ログ管理標準出力のみローテーション設定
ボリュームマウント読み書き可読み取り専用(:ro)

0-4. 本番環境の要件

【本番環境の5つの要件】 1. 高可用性 2. セキュリティ 3. 監視 ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 自動再起動 │ │ Secrets管理 │ │ ヘルスチェック│ │ ヘルスチェック │ │ 非rootユーザー│ │ ログ集約 │ │ 冗長構成 │ │ 最小権限 │ │ メトリクス │ └──────────────┘ └──────────────┘ └──────────────┘ 4. パフォーマンス 5. 運用性 ┌──────────────┐ ┌──────────────┐ │ リソース制限 │ │ バックアップ │ │ チューニング │ │ ロールバック │ │ スケーリング │ │ ドキュメント │ └──────────────┘ └──────────────┘

📂 1. プロジェクト構造の作成

# プロジェクトディレクトリ作成 mkdir -p production-deploy cd production-deploy # ディレクトリ構成 mkdir -p config/{dev,prod} mkdir -p scripts mkdir -p src mkdir -p data/input mkdir -p logs mkdir -p backups # 構造確認 tree -L 2 . || find . -type d
📁 最終的なディレクトリ構造
production-deploy/ ├── docker-compose.dev.yml # 開発環境設定 ├── docker-compose.prod.yml # 本番環境設定 ├── Dockerfile # マルチステージビルド ├── requirements.txt # Python依存関係 ├── init.sql # DB初期化 ├── config/ │ ├── dev/ │ │ └── .env.dev # 開発環境変数 │ └── prod/ │ ├── .env.prod # 本番環境変数 │ └── db_password.txt # シークレット(Git管理外) ├── scripts/ │ ├── deploy.sh # デプロイスクリプト │ ├── backup.sh # バックアップ │ ├── rollback.sh # ロールバック │ └── health_check.sh # ヘルスチェック ├── src/ # アプリケーションコード │ └── …(STEP 26と同じ) ├── data/ │ └── input/ │ └── sales_data.csv ├── logs/ # ログファイル └── backups/ # バックアップファイル

🔐 2. 環境設定ファイルの作成

2-1. 開発環境の設定

# 開発環境の環境変数 cat > config/dev/.env.dev << ‘EOF’ # 開発環境設定 ENV=development DEBUG=true LOG_LEVEL=DEBUG # データベース DB_NAME=dev_datawarehouse DB_USER=dev_user DB_PASSWORD=dev_password_123 # ETL設定 BATCH_SIZE=100 MAX_RETRIES=1 EOF echo “✅ 開発環境設定ファイル作成完了”

2-2. 本番環境の設定

# 本番環境の環境変数 cat > config/prod/.env.prod << ‘EOF’ # 本番環境設定 ENV=production DEBUG=false LOG_LEVEL=WARNING VERSION=1.0.0 # データベース DB_NAME=prod_datawarehouse DB_USER=prod_user # パスワードはDocker Secretsで管理 # ETL設定 BATCH_SIZE=5000 MAX_RETRIES=5 EOF # シークレットファイル(Git管理外) cat > config/prod/db_password.txt << ‘EOF’ very_secure_production_password_456 EOF # 権限を制限 chmod 600 config/prod/db_password.txt echo “✅ 本番環境設定ファイル作成完了”
⚠️ セキュリティ注意
  • db_password.txt絶対にGitにコミットしない
  • 本番パスワードは専用のシークレット管理ツールで管理(HashiCorp Vault等)
  • ファイル権限は600(所有者のみ読み書き可)に設定
# .gitignoreに追加 cat >> .gitignore << ‘EOF’ config/prod/db_password.txt *.txt backups/ logs/ EOF

⚙️ 3. 開発環境のDocker Compose

# 開発環境用docker-compose.dev.yml cat > docker-compose.dev.yml << ‘EOF’ version: ‘3.8’ services: # ============================================ # PostgreSQL(開発環境) # ============================================ postgres: image: postgres:15 container_name: dev-postgres environment: POSTGRES_DB: ${DB_NAME} POSTGRES_USER: ${DB_USER} POSTGRES_PASSWORD: ${DB_PASSWORD} ports: – “5432:5432” volumes: – postgres_dev_data:/var/lib/postgresql/data – ./init.sql:/docker-entrypoint-initdb.d/init.sql networks: – dev-network # 開発環境ではヘルスチェックなし、再起動なし # ============================================ # ETL(開発環境) # ============================================ etl: build: context: . dockerfile: Dockerfile target: development # 開発用ステージを使用 container_name: dev-etl environment: ENV: development DEBUG: “true” LOG_LEVEL: DEBUG DB_HOST: postgres DB_PORT: 5432 DB_NAME: ${DB_NAME} DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} volumes: – ./src:/app/src # ホットリロード用 – ./data:/data – ./logs:/logs networks: – dev-network depends_on: – postgres # 開発中は待機状態 command: tail -f /dev/null networks: dev-network: driver: bridge volumes: postgres_dev_data: EOF echo “✅ docker-compose.dev.yml 作成完了”

🏭 4. 本番環境のDocker Compose

# 本番環境用docker-compose.prod.yml cat > docker-compose.prod.yml << ‘EOF’ version: ‘3.8’ services: # ============================================ # PostgreSQL(本番環境) # ============================================ postgres: image: postgres:15 container_name: prod-postgres environment: POSTGRES_DB: ${DB_NAME} POSTGRES_USER: ${DB_USER} # パスワードはSecretから読み込み POSTGRES_PASSWORD_FILE: /run/secrets/db_password secrets: – db_password ports: – “5432:5432” volumes: – postgres_prod_data:/var/lib/postgresql/data – ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro – ./backups:/backups networks: – prod-network healthcheck: test: [“CMD-SHELL”, “pg_isready -U ${DB_USER} -d ${DB_NAME}”] interval: 30s timeout: 10s retries: 3 start_period: 40s restart: always deploy: resources: limits: cpus: ‘2.0’ memory: 2G reservations: cpus: ‘1.0’ memory: 1G logging: driver: “json-file” options: max-size: “10m” max-file: “3” # ============================================ # ETL(本番環境) # ============================================ etl: build: context: . dockerfile: Dockerfile target: production # 本番用ステージを使用 image: etl-pipeline:${VERSION:-latest} container_name: prod-etl environment: ENV: production DEBUG: “false” LOG_LEVEL: ${LOG_LEVEL:-WARNING} DB_HOST: postgres DB_PORT: 5432 DB_NAME: ${DB_NAME} DB_USER: ${DB_USER} BATCH_SIZE: ${BATCH_SIZE:-5000} MAX_RETRIES: ${MAX_RETRIES:-5} secrets: – db_password volumes: – ./data/input:/data/input:ro # 読み取り専用 – ./data/output:/data/output – ./logs:/logs networks: – prod-network depends_on: postgres: condition: service_healthy restart: always deploy: resources: limits: cpus: ‘1.5’ memory: 1G reservations: cpus: ‘0.5’ memory: 512M healthcheck: test: [“CMD”, “python”, “-c”, “from src.config import Config; Config.validate()”] interval: 60s timeout: 10s retries: 3 start_period: 30s logging: driver: “json-file” options: max-size: “50m” max-file: “5” # ============================================ # Secrets(Docker Secrets) # ============================================ secrets: db_password: file: ./config/prod/db_password.txt # ============================================ # Networks # ============================================ networks: prod-network: driver: bridge # ============================================ # Volumes # ============================================ volumes: postgres_prod_data: EOF echo “✅ docker-compose.prod.yml 作成完了”
🔐 本番環境の重要な設定
  • Docker Secrets:POSTGRES_PASSWORD_FILEでファイルからパスワードを読み込み
  • restart: always:異常終了時やDocker再起動時に自動再起動
  • ヘルスチェック:30秒間隔でPostgreSQLとETLの健全性を監視
  • リソース制限:CPU・メモリの上限と予約を設定
  • ログローテーション:max-sizemax-fileでディスク容量を保護
  • 読み取り専用:入力データは:roでセキュリティ向上

🐳 5. マルチステージDockerfile

# マルチステージDockerfile cat > Dockerfile << ‘EOF’ # ============================================ # ベースイメージ # ============================================ FROM python:3.11-slim as base LABEL maintainer=”dataeng” \ version=”1.0″ \ description=”ETL Pipeline Container” WORKDIR /app # 非rootユーザー作成 RUN useradd -m -u 1000 -s /bin/bash etluser # ============================================ # 開発環境ステージ # ============================================ FROM base as development # 依存関係インストール COPY requirements.txt . RUN pip install –no-cache-dir -r requirements.txt # アプリケーションコード(開発時はボリュームマウントで上書き) COPY –chown=etluser:etluser src/ ./src/ # 必要なディレクトリ作成 RUN mkdir -p /data/input /data/output /logs && \ chown -R etluser:etluser /data /logs /app USER etluser ENV PYTHONUNBUFFERED=1 \ PYTHONPATH=/app # 開発時は待機 CMD [“tail”, “-f”, “/dev/null”] # ============================================ # ビルドステージ(本番用) # ============================================ FROM base as builder COPY requirements.txt . RUN pip install –no-cache-dir –user -r requirements.txt # ============================================ # 本番環境ステージ # ============================================ FROM base as production # Pythonパッケージをビルダーからコピー COPY –from=builder /root/.local /home/etluser/.local # アプリケーションコードをコピー COPY –chown=etluser:etluser src/ ./src/ # 必要なディレクトリ作成 RUN mkdir -p /data/input /data/output /logs && \ chown -R etluser:etluser /data /logs /app # 非rootユーザーに切り替え USER etluser # 環境変数 ENV PATH=/home/etluser/.local/bin:$PATH \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONPATH=/app # ヘルスチェック HEALTHCHECK –interval=30s –timeout=10s –start-period=5s –retries=3 \ CMD python -c “from src.config import Config; Config.validate()” || exit 1 # デフォルトコマンド CMD [“python”, “-m”, “src.etl”, “sales_data.csv”] EOF echo “✅ Dockerfile 作成完了”

📜 6. デプロイ・運用スクリプト

6-1. デプロイスクリプト

# scripts/deploy.sh cat > scripts/deploy.sh << ‘EOF’ #!/bin/bash set -e echo “🚀 ======================================” echo “🚀 本番環境デプロイ開始” echo “🚀 ======================================” # 環境変数読み込み export $(cat config/prod/.env.prod | grep -v ‘^#’ | xargs) # バージョン確認 echo “” echo “📦 デプロイバージョン: ${VERSION}” echo “📅 日時: $(date ‘+%Y-%m-%d %H:%M:%S’)” echo “” read -p “このバージョンでデプロイしますか? (y/n): ” -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo “❌ デプロイをキャンセルしました” exit 1 fi # イメージビルド echo “” echo “🔨 Dockerイメージをビルド中…” docker build \ –target production \ –tag etl-pipeline:${VERSION} \ –tag etl-pipeline:latest \ . # 既存のバックアップ作成 echo “” echo “💾 データベースのバックアップ作成中…” if docker ps | grep -q prod-postgres; then ./scripts/backup.sh else echo ” ⚠️ PostgreSQLコンテナが起動していないためスキップ” fi # 古いコンテナを停止 echo “” echo “⏸️ 既存のコンテナを停止中…” docker-compose -f docker-compose.prod.yml –env-file config/prod/.env.prod down 2>/dev/null || true # 新しいコンテナを起動 echo “” echo “▶️ 新しいコンテナを起動中…” docker-compose -f docker-compose.prod.yml –env-file config/prod/.env.prod up -d # ヘルスチェック待機 echo “” echo “⏳ コンテナの起動を待機中(30秒)…” sleep 30 # ヘルスチェック echo “” echo “🏥 ヘルスチェック実行中…” ./scripts/health_check.sh if [ $? -eq 0 ]; then echo “” echo “✅ ======================================” echo “✅ デプロイ完了!” echo “✅ ======================================” echo “” echo “📊 ログ確認コマンド:” echo ” docker-compose -f docker-compose.prod.yml logs -f” else echo “” echo “❌ ======================================” echo “❌ デプロイ失敗” echo “❌ ======================================” echo “” echo “🔙 ロールバックを実行してください:” echo ” ./scripts/rollback.sh” exit 1 fi EOF chmod +x scripts/deploy.sh echo “✅ deploy.sh 作成完了”

6-2. バックアップスクリプト

# scripts/backup.sh cat > scripts/backup.sh << ‘EOF’ #!/bin/bash set -e BACKUP_DIR=”./backups” TIMESTAMP=$(date +%Y%m%d_%H%M%S) BACKUP_FILE=”backup_${TIMESTAMP}.dump” # 環境変数読み込み export $(cat config/prod/.env.prod | grep -v ‘^#’ | xargs) mkdir -p ${BACKUP_DIR} echo “💾 データベースバックアップ開始…” echo ” 対象: ${DB_NAME}” echo ” ファイル: ${BACKUP_DIR}/${BACKUP_FILE}” # pg_dumpでバックアップ(カスタム形式) docker exec prod-postgres pg_dump \ -U ${DB_USER} \ -d ${DB_NAME} \ -F c \ -f /backups/${BACKUP_FILE} # バックアップファイルのサイズ確認 BACKUP_SIZE=$(ls -lh ${BACKUP_DIR}/${BACKUP_FILE} | awk ‘{print $5}’) echo “✅ バックアップ完了: ${BACKUP_FILE} (${BACKUP_SIZE})” # 古いバックアップを削除(7日以上前) OLD_COUNT=$(find ${BACKUP_DIR} -name “backup_*.dump” -mtime +7 | wc -l) if [ $OLD_COUNT -gt 0 ]; then find ${BACKUP_DIR} -name “backup_*.dump” -mtime +7 -delete echo “🗑️ 古いバックアップを ${OLD_COUNT} 件削除しました” fi # バックアップ一覧 echo “” echo “📁 現在のバックアップ一覧:” ls -lh ${BACKUP_DIR}/backup_*.dump 2>/dev/null || echo ” バックアップなし” EOF chmod +x scripts/backup.sh echo “✅ backup.sh 作成完了”

6-3. ロールバックスクリプト

# scripts/rollback.sh cat > scripts/rollback.sh << ‘EOF’ #!/bin/bash set -e echo “🔙 ======================================” echo “🔙 ロールバック開始” echo “🔙 ======================================” # 環境変数読み込み export $(cat config/prod/.env.prod | grep -v ‘^#’ | xargs) # 最新のバックアップを確認 LATEST_BACKUP=$(ls -t backups/backup_*.dump 2>/dev/null | head -1) if [ -z “$LATEST_BACKUP” ]; then echo “❌ バックアップファイルが見つかりません” exit 1 fi echo “” echo “📦 利用可能なバックアップ:” ls -lh backups/backup_*.dump echo “” echo “📦 選択されたバックアップ: ${LATEST_BACKUP}” echo “” read -p “このバックアップでロールバックしますか? (y/n): ” -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo “❌ ロールバックをキャンセルしました” exit 1 fi # PostgreSQLのみ起動 echo “” echo “⏸️ ETLコンテナを停止中…” docker-compose -f docker-compose.prod.yml –env-file config/prod/.env.prod stop etl echo “” echo “🔄 データベースをリストア中…” # リストア実行 BACKUP_FILENAME=$(basename ${LATEST_BACKUP}) docker exec prod-postgres pg_restore \ -U ${DB_USER} \ -d ${DB_NAME} \ -c \ /backups/${BACKUP_FILENAME} || true # ETLコンテナを再起動 echo “” echo “▶️ ETLコンテナを再起動中…” docker-compose -f docker-compose.prod.yml –env-file config/prod/.env.prod start etl echo “” echo “✅ ======================================” echo “✅ ロールバック完了” echo “✅ ======================================” EOF chmod +x scripts/rollback.sh echo “✅ rollback.sh 作成完了”

6-4. ヘルスチェックスクリプト

# scripts/health_check.sh cat > scripts/health_check.sh << ‘EOF’ #!/bin/bash echo “🏥 ヘルスチェック開始…” echo “” EXIT_CODE=0 # 環境変数読み込み export $(cat config/prod/.env.prod | grep -v ‘^#’ | xargs) # 1. PostgreSQLチェック echo “📊 [1/4] PostgreSQL…” if docker exec prod-postgres pg_isready -U ${DB_USER} -d ${DB_NAME} > /dev/null 2>&1; then echo ” ✅ PostgreSQL: 正常” else echo ” ❌ PostgreSQL: 異常” EXIT_CODE=1 fi # 2. ETLコンテナチェック echo “🔄 [2/4] ETLコンテナ…” CONTAINER_STATUS=$(docker inspect -f ‘{{.State.Status}}’ prod-etl 2>/dev/null || echo “not found”) if [ “$CONTAINER_STATUS” = “running” ]; then echo ” ✅ ETLコンテナ: 実行中” else echo ” ❌ ETLコンテナ: ${CONTAINER_STATUS}” EXIT_CODE=1 fi # 3. ディスク容量チェック echo “💾 [3/4] ディスク容量…” DISK_USAGE=$(df -h / | awk ‘NR==2 {print $5}’ | sed ‘s/%//’) if [ $DISK_USAGE -lt 80 ]; then echo ” ✅ ディスク使用率: ${DISK_USAGE}% (正常)” elif [ $DISK_USAGE -lt 90 ]; then echo ” ⚠️ ディスク使用率: ${DISK_USAGE}% (警告)” else echo ” ❌ ディスク使用率: ${DISK_USAGE}% (危険)” EXIT_CODE=1 fi # 4. メモリ使用量チェック echo “🧠 [4/4] メモリ使用量…” MEMORY_USAGE=$(docker stats –no-stream –format “{{.MemPerc}}” prod-postgres prod-etl 2>/dev/null | head -1 | sed ‘s/%//’) if [ -n “$MEMORY_USAGE” ]; then echo ” ✅ コンテナメモリ: 確認済み” else echo ” ⚠️ メモリ使用量: 取得できません” fi echo “” if [ $EXIT_CODE -eq 0 ]; then echo “✅ すべてのヘルスチェック完了” else echo “❌ ヘルスチェックに失敗した項目があります” fi exit $EXIT_CODE EOF chmod +x scripts/health_check.sh echo “✅ health_check.sh 作成完了”

✅ 7. デプロイチェックリスト

📋 デプロイ前チェックリスト
  • 環境変数ファイル(.env.prod)の値を確認
  • シークレットファイル(db_password.txt)が存在する
  • Dockerイメージのビルドが成功する
  • 最新のデータベースバックアップを取得済み
  • リソース制限の設定値が適切
  • ヘルスチェックの設定が正しい
  • ログローテーション設定を確認
  • ネットワーク設定を確認
  • バージョン番号を更新した
  • ロールバック手順を確認した
📋 デプロイ後チェックリスト
  • すべてのコンテナが起動している
  • ヘルスチェックスクリプトが成功
  • ログが正常に出力されている
  • データベース接続が成功
  • ETL処理が正常に実行される
  • リソース使用率が正常範囲内
  • ディスク容量に余裕がある(80%未満)
  • エラーログがない

🚀 8. デプロイ実行手順

8-1. 開発環境でテスト

# 開発環境で動作確認 docker-compose -f docker-compose.dev.yml \ –env-file config/dev/.env.dev up -d # コンテナ状態確認 docker-compose -f docker-compose.dev.yml ps # 手動でETL実行テスト docker-compose -f docker-compose.dev.yml exec etl \ python -m src.etl sales_data.csv # 問題なければ停止 docker-compose -f docker-compose.dev.yml down

8-2. 本番デプロイ実行

# デプロイスクリプトを実行 ./scripts/deploy.sh
🚀 ====================================== 🚀 本番環境デプロイ開始 🚀 ====================================== 📦 デプロイバージョン: 1.0.0 📅 日時: 2024-01-20 10:30:00 このバージョンでデプロイしますか? (y/n): y 🔨 Dockerイメージをビルド中… [+] Building 15.2s (12/12) FINISHED => => naming to docker.io/library/etl-pipeline:1.0.0 💾 データベースのバックアップ作成中… ✅ バックアップ完了: backup_20240120_103015.dump (256K) ⏸️ 既存のコンテナを停止中… ▶️ 新しいコンテナを起動中… ⏳ コンテナの起動を待機中(30秒)… 🏥 ヘルスチェック実行中… 📊 [1/4] PostgreSQL… ✅ PostgreSQL: 正常 🔄 [2/4] ETLコンテナ… ✅ ETLコンテナ: 実行中 💾 [3/4] ディスク容量… ✅ ディスク使用率: 45% (正常) 🧠 [4/4] メモリ使用量… ✅ コンテナメモリ: 確認済み ✅ すべてのヘルスチェック完了 ✅ ====================================== ✅ デプロイ完了! ✅ ======================================

8-3. 動作確認

# コンテナ状態確認 docker-compose -f docker-compose.prod.yml ps # リソース使用状況 docker stats –no-stream prod-postgres prod-etl # ログ確認 docker-compose -f docker-compose.prod.yml logs –tail 50 # データベース確認 docker exec prod-postgres psql -U prod_user -d prod_datawarehouse \ -c “SELECT COUNT(*) FROM sales;”

🔄 9. 運用タスク

9-1. 定期バックアップ(Cron設定)

# crontabを編集 crontab -e # 毎日午前2時にバックアップ 0 2 * * * cd /path/to/production-deploy && ./scripts/backup.sh >> logs/backup.log 2>&1 # 毎時ヘルスチェック 0 * * * * cd /path/to/production-deploy && ./scripts/health_check.sh >> logs/health.log 2>&1

9-2. ログの確認

# リアルタイムログ docker-compose -f docker-compose.prod.yml logs -f # 特定のサービスのみ docker-compose -f docker-compose.prod.yml logs -f etl # 最新100行(タイムスタンプ付き) docker-compose -f docker-compose.prod.yml logs –tail 100 -t # エラーログのみ抽出 docker-compose -f docker-compose.prod.yml logs 2>&1 | grep -i error

9-3. ディスク容量管理

# ディスク使用状況 df -h # Dockerのディスク使用状況 docker system df # 未使用リソースのクリーンアップ(注意して実行) docker system prune -a –volumes # 古いイメージのみ削除 docker image prune -a –filter “until=168h” # 7日以上前

9-4. コンテナの再起動

# 特定のサービスを再起動 docker-compose -f docker-compose.prod.yml –env-file config/prod/.env.prod restart etl # すべてのサービスを再起動 docker-compose -f docker-compose.prod.yml –env-file config/prod/.env.prod restart # 設定変更後の再起動(コンテナ再作成) docker-compose -f docker-compose.prod.yml –env-file config/prod/.env.prod up -d –force-recreate

💪 10. 練習問題

練習問題 1 基礎

開発環境と本番環境で異なる設定を3つ挙げて、その理由を説明してください。

  1. ログレベル(DEBUG→WARNING):本番では不要な詳細ログを抑制してパフォーマンス向上とディスク節約
  2. 再起動ポリシー(no→always):本番では障害時に自動復旧して可用性を確保
  3. パスワード管理(.env→Secrets):本番ではより安全な方法で機密情報を管理
練習問題 2 基礎

Docker Secretsを使う利点は何ですか?

  • 環境変数より安全:環境変数はdocker inspectで見えてしまうが、Secretsはメモリ上のみで管理
  • ファイルシステム経由:/run/secrets/にマウントされ、コンテナ内からファイルとして読み取り
  • 暗号化保存:Swarm Modeでは暗号化されて保存される
  • アクセス制限:必要なコンテナのみがSecretにアクセス可能
練習問題 3 応用

ログローテーションの設定(max-size: 50m, max-file: 5)の意味と、この設定で使用される最大ディスク容量を計算してください。

設定の意味:

  • max-size: 50m: 1つのログファイルの最大サイズは50MB
  • max-file: 5: 保持するログファイルの最大数は5個

最大ディスク容量:

50MB × 5ファイル = 250MB(1コンテナあたり)

PostgreSQL + ETL = 250MB × 2 = 500MB(システム全体)

練習問題 4 応用

バックアップスクリプトを週次バックアップ(毎週日曜午前3時)に変更するCron設定を書いてください。

# 毎週日曜日の午前3時に実行 0 3 * * 0 cd /path/to/production-deploy && ./scripts/backup.sh >> logs/backup.log 2>&1 # Cron形式の説明 # ┌───────────── 分 (0-59) # │ ┌─────────── 時 (0-23) # │ │ ┌───────── 日 (1-31) # │ │ │ ┌─────── 月 (1-12) # │ │ │ │ ┌───── 曜日 (0-6, 0=日曜) # │ │ │ │ │ # 0 3 * * 0
練習問題 5 発展

ゼロダウンタイムデプロイ(無停止デプロイ)を実現するための方法を2つ説明してください。

方法1: ブルー・グリーンデプロイメント

  • 現在稼働中の環境(ブルー)とは別に、新バージョンの環境(グリーン)を構築
  • グリーン環境でテスト完了後、ロードバランサーで切り替え
  • 問題発生時は即座にブルーに戻せる

方法2: ローリングアップデート(Kubernetes/Docker Swarm)

  • 複数のレプリカを順番に新バージョンに更新
  • 常に一部のコンテナが稼働中
  • docker service update --update-parallelism 1で制御

📝 STEP 27 のまとめ

✅ このプロジェクトで習得したスキル
  • 環境分離:開発環境と本番環境の設定を完全に分離
  • シークレット管理:Docker Secretsによる安全なパスワード管理
  • マルチステージビルド:開発用・本番用のステージを1つのDockerfileで管理
  • リソース制限:CPU・メモリの制限と予約の設定
  • ログ管理:ログローテーションによるディスク容量保護
  • 運用自動化:デプロイ、バックアップ、ヘルスチェックのスクリプト化
  • チェックリスト:デプロイ前後の確認項目の整理
📊 本番環境運用の重要ポイント
カテゴリポイント実装方法
自動化人的ミスを防止deploy.sh, backup.sh
監視異常の早期発見health_check.sh, ヘルスチェック
バックアップデータ損失防止pg_dump, Cron設定
セキュリティ機密情報保護Docker Secrets, 非rootユーザー
可用性サービス継続restart: always, ヘルスチェック

🎉 コース完了おめでとうございます!

✨ このコースで学んだこと
  • Part 1-2(STEP 1-10):Dockerの基礎とイメージ管理
  • Part 3(STEP 11-14):Dockerfileの作成と最適化
  • Part 4(STEP 15-18):Docker Composeとネットワーキング
  • Part 5(STEP 19-24):データエンジニアリング実践
  • Part 6(STEP 25-27):総合演習と本番デプロイ
🚀 次のステップ
  • Kubernetes:より大規模なシステムのオーケストレーション
  • CI/CD深掘り:GitHub Actions、GitLab CI、ArgoCD
  • クラウド:AWS ECS/EKS、Google Cloud Run/GKE、Azure AKS
  • モニタリング:Prometheus、Grafana、Datadog
  • セキュリティ:Trivy、Falco、OPA
💼 実務での活用

このコースで学んだスキルは、データエンジニアとして即座に実務で活用できます。

  • ETLパイプラインのコンテナ化と運用
  • PostgreSQL、Airflow、Sparkの環境構築
  • 開発環境の標準化とチーム共有
  • CI/CDパイプラインの構築
  • 本番環境へのデプロイと運用

🎓 コース完了

全27ステップをクリアしました!
あなたはDockerとコンテナ技術を実務レベルで扱えるデータエンジニアです。

📝

学習メモ

Docker・コンテナ技術入門 - Step 27

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE