STEP 16:docker-compose.ymlの書き方

📝 STEP 16: docker-compose.ymlの書き方

実践的な設定方法をマスターして、プロの環境を構築する

📋 このステップで学ぶこと

  • services、networks、volumesの詳細
  • イメージ指定とビルド指定の使い分け
  • ポートマッピングの設定方法
  • 環境変数の設定(.envファイル含む)
  • depends_on(依存関係)の活用
  • 実践演習で2つのコンテナを連携

🔧 0. このステップの前提知識

📚 STEP 15の復習

このステップでは、以下の知識を使います。忘れた場合は復習してから進めましょう。

  • Docker Compose:複数コンテナを管理するツール
  • docker-compose up -d:全サービスをバックグラウンドで起動
  • docker-compose down:全サービスを停止・削除
  • サービス名での通信:コンテナ間はサービス名でアクセス

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

# 作業ディレクトリを作成して移動 mkdir -p ~/docker-practice/step16 cd ~/docker-practice/step16 # 現在の場所を確認 pwd

0-2. docker-compose.ymlの全体構造

このステップでは、docker-compose.ymlの各設定項目を詳しく学びます。
まず全体像を把握しましょう。

【docker-compose.ymlの全体構造】 docker-compose.yml ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ version: ‘3.8’ ← ① バージョン(3.8を使えばOK) services: ← ② サービス定義(最重要!) webapp: 各コンテナの設定を記述 image: … build: … ports: … environment: … volumes: … depends_on: … networks: ← ③ ネットワーク定義(省略可) mynetwork: コンテナ間の通信設定 volumes: ← ④ ボリューム定義(省略可) mydata: データ永続化の設定 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 💡 このステップでは②servicesの各設定項目を詳しく学びます

0-3. このステップで学ぶ設定項目

STEP 16で学ぶ主要設定項目
設定項目 役割
image 既存イメージを使用 image: postgres:13
build Dockerfileからビルド build: ./app
ports ポートマッピング ports: - "5000:5000"
environment 環境変数を設定 environment: DEBUG: true
env_file 外部ファイルから環境変数 env_file: - .env
volumes ボリュームマウント volumes: - data:/app/data
depends_on 起動順序の制御 depends_on: - postgres

🏗️ 1. services、networks、volumesの詳細

1-1. services(サービス)

各コンテナの設定を定義します。最も重要なセクションです。

【servicesセクションの構造】 services: サービス名: ← 自由に名前を付ける ┌─────────────────────────────────────────────┐ │ image: nginx:latest # イメージ指定 │ │ build: ./my-app # またはビルド │ │ container_name: my_nginx # コンテナ名固定 │ │ ports: # ポートマッピング │ │ – “8080:80” │ │ environment: # 環境変数 │ │ – KEY=value │ │ volumes: # ボリューム │ │ – ./data:/app/data │ │ networks: # ネットワーク │ │ – mynetwork │ │ depends_on: # 依存関係 │ │ – database │ │ restart: unless-stopped # 再起動ポリシー │ └─────────────────────────────────────────────┘

1-2. networks(ネットワーク)

コンテナ間の通信を設定します。省略すると自動で作成されます。

# ネットワーク定義の例 networks: # カスタムネットワーク mynetwork: driver: bridge # ドライバー(bridgeが標準) # 外部ネットワークを使う場合 existing_network: external: true
💡 ネットワークの自動作成

networks:セクションを省略すると、Docker Composeが自動でプロジェクト名_defaultという名前のネットワークを作成します。基本的には自動作成で問題ありません

1-3. volumes(ボリューム)

名前付きボリュームを定義します。データの永続化に使用します。

# ボリューム定義の例 volumes: # 基本的な定義(空でOK) postgres_data: # ドライバーを指定する場合 mydata: driver: local
🎯 バインドマウント vs 名前付きボリューム
services: myapp: volumes: # バインドマウント(ホストのパスを直接指定) – ./my-code:/app # 開発時に便利 # 名前付きボリューム(Dockerが管理) – mydata:/app/data # データ永続化に推奨 volumes: mydata: # 名前付きボリュームは宣言が必要
【バインドマウント vs 名前付きボリューム】 ┌─────────────────────────────────────────────────────────────┐ │ バインドマウント │ │ ./my-code:/app │ ├─────────────────────────────────────────────────────────────┤ │ ホスト コンテナ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ ./my-code/ │ ───────── │ /app/ │ │ │ │ ├── app.py │ 直接 │ ├── app.py │ │ │ │ └── … │ 同期 │ └── … │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ 💡 開発時:ホストでコードを編集 → コンテナに即反映 │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ 名前付きボリューム │ │ mydata:/app/data │ ├─────────────────────────────────────────────────────────────┤ │ Docker管理領域 コンテナ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ mydata │ ───────── │ /app/data │ │ │ │ (自動管理) │ Docker │ │ │ │ │ │ が管理 │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ 💡 本番時:データベースなど永続化が必要なデータに使用 │ └─────────────────────────────────────────────────────────────┘

🖼️ 2. イメージ指定とビルド指定

2-1. image:既存イメージを使う

Docker Hubや他のレジストリからイメージを取得して使用します。

services: # Docker Hubの公式イメージ postgres: image: postgres:13 # バージョンタグ指定 redis: image: redis:6.2-alpine # プライベートレジストリ myapp: image: myregistry.com/myapp:latest

2-2. build:Dockerfileからビルド

カスタムイメージをビルドして使用します。

services: # 1. シンプルな指定(Dockerfileがあるディレクトリ) webapp: build: ./app # 2. 詳細な指定 api: build: context: ./api # ビルドコンテキスト dockerfile: Dockerfile.prod # Dockerfileの名前 args: # ビルド引数 – VERSION=1.0.0 – DEBUG=false # 3. imageも一緒に指定(ビルド後のタグ名) backend: build: ./backend image: mybackend:latest # ビルドしたイメージに名前を付ける

2-3. imageとbuildの使い分け

imageとbuildの使い分け
使用ケース 使う設定
公式イメージを使う image:のみ PostgreSQL、Redis、Nginx
カスタムアプリ build:のみ 自作のFlaskアプリ
ビルド+タグ付け 両方 レジストリにプッシュする場合

2-4. プロジェクト構成例

【プロジェクト構成例】 myproject/ ├── docker-compose.yml ├── frontend/ ← build: ./frontend │ ├── Dockerfile │ ├── package.json │ └── src/ ├── backend/ ← build: ./backend │ ├── Dockerfile │ ├── requirements.txt │ └── app.py └── nginx/ ← build: ./nginx ├── Dockerfile └── nginx.conf postgres、redis ← image: postgres:13, image: redis:alpine (公式イメージを使用)
# docker-compose.yml version: ‘3.8’ services: # フロントエンド(ビルド) frontend: build: ./frontend image: myapp-frontend:latest # バックエンド(ビルド) backend: build: ./backend image: myapp-backend:latest # データベース(既存イメージ) postgres: image: postgres:13 # Nginx(ビルド) nginx: build: ./nginx image: myapp-nginx:latest ports: – “80:80”

🔌 3. ポートマッピングの設定

3-1. 基本的なポートマッピング

ホストとコンテナのポートを対応付けます。

services: webapp: image: nginx ports: # 形式: “ホストポート:コンテナポート” – “8080:80” # ホストの8080 → コンテナの80 – “8443:443” # ホストの8443 → コンテナの443 # コンテナポートだけ指定(ホストはランダム) – “3000” # IPアドレスも指定 – “127.0.0.1:8080:80” # localhostだけアクセス可
【ポートマッピングの動作】 ブラウザ ホスト コンテナ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ localhost │ │ Docker │ │ │ アクセス │ ──────────▶ │ :8080 │ ─────────▶ │ :80 │ │ │ :8080 │ │ 内部通信 │ nginx │ └─────────┘ └─────────┘ └─────────┘ ports: – “8080:80” ↑ ↑ │ └─ コンテナ内のポート └─────── ホストのポート(外部からアクセス)
⚠️ ポート番号は必ず引用符で囲む
ports: – “8080:80” # ✅ 正しい(引用符あり) – 8080:80 # ⚠️ YAMLが時刻と解釈する可能性

特に60:60などは時刻として解釈される場合があるため、常に引用符を使いましょう

3-2. portsとexposeの違い

services: # ports:外部(ホスト)に公開 frontend: image: nginx ports: – “80:80” # ホストの80番でアクセス可能 # expose:内部のみ公開(他のコンテナから) backend: image: myapi expose: – “5000” # 他のコンテナから5000番でアクセス可能 # ホストからはアクセス不可
portsとexposeの違い
設定 アクセス範囲 使用例
ports ホスト+他のコンテナ Webサーバー、管理画面
expose 他のコンテナのみ 内部API、データベース

3-3. ポート番号の重複に注意

⚠️ よくあるエラー:ポートの重複
services: service1: ports: – “5000:5000” service2: ports: – “5000:5000” # ❌ エラー:ホストの5000は既に使用中

解決策:ホスト側のポートを変える

services: service1: ports: – “5000:5000” # ✅ OK service2: ports: – “5001:5000” # ✅ OK(ホスト側を5001に変更)

🔧 4. 環境変数の設定

4-1. 方法1:environmentで直接指定

services: webapp: image: myapp:latest environment: # 方法A:リスト形式 – DATABASE_URL=postgresql://user:pass@postgres:5432/db – DEBUG=true – PORT=5000 # 方法B:辞書形式 DATABASE_URL: postgresql://user:pass@postgres:5432/db DEBUG: “true” PORT: “5000”

4-2. 方法2:env_fileで外部ファイルから読み込み

# .envファイルを作成 cat > .env << ‘EOF’ DATABASE_URL=postgresql://user:pass@postgres:5432/db DEBUG=true PORT=5000 SECRET_KEY=my-secret-key EOF
# docker-compose.yml services: webapp: image: myapp:latest env_file: – .env # .envファイルから読み込む # 複数ファイルも可能 backend: image: backend:latest env_file: – .env.common – .env.production
💡 .envファイルの利点
  • 機密情報の分離:.envを.gitignoreに追加してGitに含めない
  • 環境ごとの切り替え:.env.dev、.env.prod で分ける
  • 管理が楽:環境変数を1ファイルに集約

4-3. 方法3:ホストの環境変数を使う

# docker-compose.yml services: webapp: image: myapp:latest environment: # ${変数名}でホストの環境変数を参照 DATABASE_URL: ${DATABASE_URL} SECRET_KEY: ${SECRET_KEY} # デフォルト値も指定可能 DEBUG: ${DEBUG:-false} # DEBUGがなければfalse
# 使用例:ホスト側で環境変数を設定してから起動 export DATABASE_URL=postgresql://localhost/mydb export SECRET_KEY=supersecret docker-compose up -d

4-4. 環境変数の優先順位

📊 優先順位(高い → 低い)
  1. docker-composeコマンドの-eオプション
  2. docker-compose.ymlのenvironment:
  3. env_file:で指定したファイル
  4. ホストの環境変数
  5. DockerfileのENV

4-5. 実践例:PostgreSQL接続設定

# .envファイルを作成 cat > .env << ‘EOF’ POSTGRES_USER=myuser POSTGRES_PASSWORD=mypassword POSTGRES_DB=mydb DATABASE_URL=postgresql://myuser:mypassword@postgres:5432/mydb EOF
# docker-compose.yml version: ‘3.8’ services: postgres: image: postgres:13 env_file: – .env volumes: – postgres_data:/var/lib/postgresql/data webapp: build: ./app env_file: – .env depends_on: – postgres volumes: postgres_data:

⚡ 5. depends_on(依存関係)

5-1. 基本的な使い方

起動順序を制御します。

services: # データベース(最初に起動) postgres: image: postgres:13 # Webアプリ(postgresの後に起動) webapp: image: myapp:latest depends_on: – postgres # postgresを起動してから、webappを起動 # Nginx(webappの後に起動) nginx: image: nginx depends_on: – webapp # webappを起動してから、nginxを起動
【depends_onによる起動順序】 ┌─────────────────────────────────────────────────────────────┐ │ 起動順序 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 時間 ─────────────────────────────────────────────────▶ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ postgres │───▶│ webapp │───▶│ nginx │ │ │ │ (起動) │ │ (起動) │ │ (起動) │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ depends_on: depends_on: │ │ なし – postgres – webapp │ └─────────────────────────────────────────────────────────────┘
⚠️ depends_onの重要な注意点

depends_on起動順序を制御しますが、サービスが準備完了するまで待たないことに注意!

【よくある問題】 時間 ─────────────────────────────────────────────────────▶ postgres コンテナ起動 │ ├── PostgreSQLが初期化中…(数秒かかる) │ │ webapp コンテナ起動(depends_onによりpostgres起動後) │ │ │ └── PostgreSQLに接続試行 → ❌ 接続失敗! │ (PostgreSQLがまだ準備完了していない) │ └── PostgreSQL準備完了

5-2. 解決策:アプリ側でリトライ実装

# app.py(Python例) import time import psycopg2 import os def connect_to_db(): “””データベース接続(リトライ付き)””” max_retries = 5 retry_interval = 2 # 秒 for i in range(max_retries): try: conn = psycopg2.connect(os.environ[‘DATABASE_URL’]) print(“データベース接続成功!”) return conn except Exception as e: print(f”接続失敗({i+1}/{max_retries}): {e}”) if i < max_retries - 1: time.sleep(retry_interval) else: raise # アプリ起動時に接続 conn = connect_to_db()

5-3. 複数の依存関係

services: postgres: image: postgres:13 redis: image: redis:alpine rabbitmq: image: rabbitmq:management # 複数のサービスに依存 webapp: image: myapp:latest depends_on: – postgres – redis – rabbitmq

🛠️ 6. 実践演習:Flask + PostgreSQLの連携

6-1. 演習の目標

FlaskアプリとPostgreSQLを連携させた環境を構築します。

📁 完成時のプロジェクト構成
flask-postgres/ ├── docker-compose.yml ├── .env ├── app/ │ ├── Dockerfile │ ├── requirements.txt │ └── app.py └── init.sql

6-2. プロジェクトディレクトリを作成

# プロジェクトディレクトリを作成 mkdir -p ~/docker-practice/flask-postgres/app cd ~/docker-practice/flask-postgres # 現在の場所を確認 pwd

6-3. .envファイルを作成

# .envファイルを作成 cat > .env << ‘EOF’ POSTGRES_USER=flaskuser POSTGRES_PASSWORD=flaskpass POSTGRES_DB=flaskdb DATABASE_URL=postgresql://flaskuser:flaskpass@postgres:5432/flaskdb EOF # 内容を確認 cat .env

6-4. app/requirements.txtを作成

# requirements.txtを作成 cat > app/requirements.txt << ‘EOF’ Flask==2.0.1 psycopg2-binary==2.9.1 EOF # 内容を確認 cat app/requirements.txt

6-5. app/Dockerfileを作成

# Dockerfileを作成 cat > app/Dockerfile << ‘EOF’ FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install –no-cache-dir -r requirements.txt COPY app.py . CMD [“python”, “app.py”] EOF # 内容を確認 cat app/Dockerfile

6-6. app/app.pyを作成

# app.pyを作成 cat > app/app.py << ‘EOF’ from flask import Flask import psycopg2 import os import time app = Flask(__name__) def get_db_connection(): “””データベース接続(リトライ付き)””” max_retries = 5 for i in range(max_retries): try: conn = psycopg2.connect(os.environ[‘DATABASE_URL’]) return conn except Exception as e: print(f”DB接続試行 {i+1}/{max_retries}: {e}”) if i < max_retries - 1: time.sleep(2) else: raise @app.route('/') def index(): return "Hello from Flask + PostgreSQL!" @app.route('/db-test') def db_test(): try: conn = get_db_connection() cur = conn.cursor() cur.execute('SELECT version();') version = cur.fetchone()[0] cur.close() conn.close() return f"PostgreSQL Version: {version}" except Exception as e: return f"Error: {e}", 500 @app.route('/users') def users(): try: conn = get_db_connection() cur = conn.cursor() cur.execute('SELECT * FROM users;') rows = cur.fetchall() cur.close() conn.close() result = "<h2>Users:</h2><ul>" for row in rows: result += f"<li>ID: {row[0]}, Name: {row[1]}, Email: {row[2]}</li>" result += "</ul>" return result except Exception as e: return f"Error: {e}", 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True) EOF # 内容を確認(先頭20行) head -20 app/app.py

6-7. init.sqlを作成

# init.sqlを作成(初期データ) cat > init.sql << ‘EOF’ CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100), email VARCHAR(100) ); INSERT INTO users (name, email) VALUES (‘Alice’, ‘alice@example.com’), (‘Bob’, ‘bob@example.com’), (‘Charlie’, ‘charlie@example.com’); EOF # 内容を確認 cat init.sql

6-8. docker-compose.ymlを作成

# docker-compose.ymlを作成 cat > docker-compose.yml << ‘EOF’ version: ‘3.8’ services: # PostgreSQLサービス postgres: image: postgres:13 container_name: flask_postgres env_file: – .env volumes: – postgres_data:/var/lib/postgresql/data – ./init.sql:/docker-entrypoint-initdb.d/init.sql ports: – “5432:5432” restart: unless-stopped # Flaskアプリ webapp: build: ./app container_name: flask_app env_file: – .env ports: – “5000:5000” depends_on: – postgres restart: unless-stopped # ボリュームの定義 volumes: postgres_data: EOF # 内容を確認 cat docker-compose.yml

6-9. ファイル構成を確認

# ファイル構成を確認 find . -type f | head -20
./.env ./init.sql ./docker-compose.yml ./app/requirements.txt ./app/Dockerfile ./app/app.py

6-10. 起動

# イメージをビルドして起動 docker-compose up –build -d # ログ確認(Ctrl+Cで終了) docker-compose logs -f
Creating network “flask-postgres_default” with the default driver Creating volume “flask-postgres_postgres_data” with default driver Building webapp … Successfully built abc123def456 Successfully tagged flask-postgres_webapp:latest Creating flask_postgres … done Creating flask_app … done

6-11. 動作確認

# サービスの状態確認 docker-compose ps
🌐 ブラウザでアクセス
  • http://localhost:5000/ → “Hello from Flask + PostgreSQL!”
  • http://localhost:5000/db-test → PostgreSQLバージョン表示
  • http://localhost:5000/users → ユーザー一覧表示

6-12. データベースに直接接続

# PostgreSQLコンテナ内でpsql起動 docker-compose exec postgres psql -U flaskuser -d flaskdb # psql内でSQL実行 # SELECT * FROM users; # \q — 終了

6-13. クリーンアップ

# 停止して削除 docker-compose down # ボリュームも削除(データが消える) docker-compose down -v # 作成したイメージも削除 docker rmi flask-postgres_webapp

💪 7. 練習問題

練習問題 1 基礎

imageとbuildの違いを説明してください。

【解答】
  • image:既存のDockerイメージを指定する。Docker Hubなどから取得。
  • build:Dockerfileからイメージをビルドする。カスタムアプリケーション用。

使い分け:

  • 公式イメージ(PostgreSQL、Redisなど)→ image:
  • 自作アプリケーション → build:
練習問題 2 基礎

portsとexposeの違いは何ですか?

【解答】
  • ports:ホストからもアクセス可能にする。外部公開。
  • expose:同じネットワーク内のコンテナからのみアクセス可能。内部公開。
services: webapp: ports: – “5000:5000” # ホストの5000番でアクセス可 backend: expose: – “8080” # 他のコンテナからのみアクセス可
練習問題 3 応用

次の要件を満たすdocker-compose.ymlを作成してください。

  • Nginx(ポート80)
  • Flask(ポート5000、./appからビルド)
  • PostgreSQL(.envファイルから環境変数)
  • FlaskはPostgreSQLの起動後に起動
  • NginxはFlaskの起動後に起動
【解答】
version: ‘3.8’ services: postgres: image: postgres:13 env_file: – .env volumes: – postgres_data:/var/lib/postgresql/data restart: unless-stopped flask: build: ./app env_file: – .env depends_on: – postgres restart: unless-stopped nginx: image: nginx:alpine ports: – “80:80” volumes: – ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: – flask restart: unless-stopped volumes: postgres_data:
練習問題 4 応用

環境変数を設定する3つの方法をそれぞれコード例で示してください。

【解答】

方法1:environmentで直接指定

services: webapp: image: myapp environment: DATABASE_URL: postgresql://user:pass@db:5432/mydb DEBUG: “true”

方法2:env_fileで外部ファイル

services: webapp: image: myapp env_file: – .env

方法3:ホストの環境変数

services: webapp: image: myapp environment: DATABASE_URL: ${DATABASE_URL} SECRET_KEY: ${SECRET_KEY:-default}
練習問題 5 応用

depends_onの注意点と、その対策を説明してください。

【解答】

注意点:

depends_onはコンテナの起動順序を制御しますが、サービスが完全に準備完了するまで待たない
例:PostgreSQLコンテナは起動しても、PostgreSQL自体の初期化には数秒かかる。

対策:

アプリ側でリトライロジックを実装する(推奨)

import time import psycopg2 def connect_db(max_retries=5): for i in range(max_retries): try: conn = psycopg2.connect(DATABASE_URL) return conn except: if i < max_retries - 1: time.sleep(2) else: raise
練習問題 6 発展

次の構成のdocker-compose.ymlを作成してください。

  • フロントエンド(React、./frontendからビルド、ポート3000)
  • バックエンド(Flask、./backendからビルド)
  • PostgreSQL(永続化あり)
  • Redis
  • Nginx(ポート80)
  • 適切な依存関係と環境変数設定
【解答】
version: ‘3.8’ services: postgres: image: postgres:13 environment: POSTGRES_USER: appuser POSTGRES_PASSWORD: apppass POSTGRES_DB: appdb volumes: – postgres_data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:alpine restart: unless-stopped backend: build: ./backend environment: DATABASE_URL: postgresql://appuser:apppass@postgres:5432/appdb REDIS_URL: redis://redis:6379 depends_on: – postgres – redis restart: unless-stopped frontend: build: ./frontend ports: – “3000:3000” environment: REACT_APP_API_URL: http://backend:5000 depends_on: – backend restart: unless-stopped nginx: image: nginx:alpine ports: – “80:80” volumes: – ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: – frontend – backend restart: unless-stopped volumes: postgres_data:
練習問題 7 発展

.envファイルを使った環境別設定を実装してください。

要件:
• .env.dev(開発環境)
• .env.prod(本番環境)
• docker-compose.dev.yml
• docker-compose.prod.yml

【解答】

.env.dev:

DEBUG=true LOG_LEVEL=DEBUG DATABASE_URL=postgresql://dev:devpass@postgres:5432/devdb

.env.prod:

DEBUG=false LOG_LEVEL=INFO DATABASE_URL=postgresql://prod:prodpass@postgres:5432/proddb

docker-compose.dev.yml:

version: ‘3.8’ services: webapp: build: ./app env_file: – .env.dev ports: – “5000:5000” volumes: – ./app:/app # ホットリロード用 postgres: image: postgres:13 env_file: – .env.dev ports: – “5432:5432” # デバッグ用に公開

使用方法:

# 開発環境 docker-compose -f docker-compose.dev.yml up # 本番環境 docker-compose -f docker-compose.prod.yml up -d
練習問題 8 応用

バインドマウントと名前付きボリュームの使い分けを説明してください。

【解答】

バインドマウント:

  • 使用場面:開発時、設定ファイル、ソースコード
  • 特徴:ホストのパスを直接指定
  • 例:./app:/app

名前付きボリューム:

  • 使用場面:データベース、本番データ
  • 特徴:Dockerが管理、バックアップしやすい
  • 例:postgres_data:/var/lib/postgresql/data
services: webapp: volumes: # バインドマウント(開発用) – ./app:/app – ./config.yml:/etc/config.yml # 名前付きボリューム(データ永続化) – app_data:/app/data volumes: app_data:
練習問題 9 基礎

docker-compose.ymlでポート番号を書く時、なぜ引用符で囲むべきですか?

【解答】

YAMLの文法上、xx:yyという形式は時刻として解釈される可能性があるためです。

ports: – 80:80 # ⚠️ 時刻と解釈される可能性 – “80:80” # ✅ 文字列として確実に解釈される

常に引用符で囲むことがベストプラクティスです。

練習問題 10 発展

マイクロサービス構成のdocker-compose.ymlを作成してください。

  • API Gateway(Nginx、ポート80)
  • User Service(./user-serviceからビルド)
  • Order Service(./order-serviceからビルド)
  • 各サービス専用のPostgreSQL
  • 共有Redis
【解答】
version: ‘3.8’ services: # User Service用DB user-db: image: postgres:13 environment: POSTGRES_DB: userdb POSTGRES_USER: useruser POSTGRES_PASSWORD: userpass volumes: – user_db_data:/var/lib/postgresql/data # Order Service用DB order-db: image: postgres:13 environment: POSTGRES_DB: orderdb POSTGRES_USER: orderuser POSTGRES_PASSWORD: orderpass volumes: – order_db_data:/var/lib/postgresql/data # 共有Redis redis: image: redis:alpine # User Service user-service: build: ./user-service environment: DATABASE_URL: postgresql://useruser:userpass@user-db:5432/userdb REDIS_URL: redis://redis:6379 depends_on: – user-db – redis # Order Service order-service: build: ./order-service environment: DATABASE_URL: postgresql://orderuser:orderpass@order-db:5432/orderdb REDIS_URL: redis://redis:6379 depends_on: – order-db – redis # API Gateway nginx: image: nginx:alpine ports: – “80:80” volumes: – ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: – user-service – order-service volumes: user_db_data: order_db_data:

📝 STEP 16 のまとめ

✅ このステップで学んだこと
  • services、networks、volumes:docker-compose.ymlの3大要素
  • imageとbuild:既存イメージか、カスタムビルドか
  • ポートマッピング:portsとexposeの使い分け
  • 環境変数:environment、env_file、ホスト変数の3つの方法
  • depends_on:起動順序の制御とリトライの重要性
  • 実践:Flask + PostgreSQLの連携を実装
📊 docker-compose.yml 主要設定早見表
設定項目 説明・例
image 既存イメージを使用:image: postgres:13
build Dockerfileからビルド:build: ./app
ports 外部公開:ports: - "8080:80"
expose 内部公開:expose: - "5000"
environment 環境変数直接指定
env_file 外部ファイルから環境変数:env_file: - .env
depends_on 起動順序制御:depends_on: - postgres
volumes ボリューム:- data:/app/data
💡 重要ポイント
  • .envファイルで機密情報を分離(.gitignoreに追加)
  • ポート番号は必ず引用符で囲む("8080:80"
  • depends_onは起動順序のみ、準備完了は待たない
  • バインドマウントは開発用、名前付きボリュームは本番用
🎯 次のステップの予告

次のSTEP 17では、「複数コンテナの連携」をさらに深く学びます。

  • PostgreSQL + pgAdminの実践的な構成
  • サービス間の通信の詳細
  • ネットワークの自動作成
  • データベース初期化

より複雑なマルチコンテナ環境を構築していきましょう!

📝

学習メモ

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

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