単一コンテナの限界とDocker Composeの必要性
前回の記事([【内部リンク】] [Docker入門完全ガイド:コンテナ化の基礎からハンズオン])で、単一のアプリケーションをDockerコンテナとして動かす基本を習得しました。しかし、現実のWebアプリケーションは、フロントエンド、バックエンドAPI、データベース、キャッシュサーバーなど、複数の独立したコンポーネント(サービス)で構成されています。
これら複数のコンテナを連携させるには、手動で複雑なネットワーク設定や起動順序の管理を行う必要があり、非常に非効率的です。
この課題をエレガントに解決するのが、Docker Composeです。Docker Composeは、複数コンテナアプリケーションの定義と実行を劇的に簡素化し、開発環境の再現性を完璧に保ちます。
1. Docker Composeとは何か?基本概念の深掘り
Docker Composeは、YAMLファイル(通常docker-compose.yml)を使用して、アプリケーションのサービス、ネットワーク、ボリュームを一元的に定義し、たった一つのコマンドでそれらを管理するためのツールです。
1-1. Docker Composeが解決する課題
- 複雑なコマンドの排除: 複数のコンテナを起動・連携させる際に必要だった長い
docker runコマンドと、ポートマッピング、ネットワーク設定をすべてYAMLファイルに集約します。 - 再現性の確保: YAMLファイルを共有するだけで、チームメンバー全員が完全に同じ本番環境に近い多層的な環境を即座に構築できます。
- 環境ライフサイクルの管理: 複数のサービスを同時に起動・停止・削除できるため、開発・テスト時の環境リセットが非常に容易になります。
1-2. Docker Composeの構成要素
docker-compose.ymlファイルは、主に以下の3つのトップレベル要素で構成されます。
| 要素名 | 役割 | 詳細 |
version | Composeファイルの仕様バージョンを指定します。最新は3.x系です。 | |
services | 起動したいコンテナ群(アプリケーションやデータベースなど)を定義します。サービス名がコンテナ間のホスト名になります。 | |
volumes | データの永続化に使用するボリュームを定義します。 | |
networks | サービス間で共有するカスタムネットワークを定義します。(指定しない場合はデフォルトネットワークが自動作成されます) |
2. 実践ハンズオン:Flask WebアプリとPostgreSQLの連携環境構築
ここでは、具体的なファイル構成と手順を通じて、Webアプリケーションサービス(Flask)とデータベースサービス(PostgreSQL)を連携させる多層環境を構築します。
2-1. プロジェクト構造のセットアップ
今回は、Webアプリのイメージ作成に必要なファイルと、Compose設定ファイルを一つのルートディレクトリにまとめます。
/docker_compose_project
├── docker-compose.yml # Compose設定ファイル(メイン)
├── web/ # Webアプリ(Flask)用のディレクトリ
│ ├── Dockerfile # Webサービスのイメージ設計図
│ ├── app.py # Pythonアプリケーション本体
│ └── requirements.txt
└── data/ # データベースの永続化データ用ディレクトリ(空でOK)
2-2. Webサービス(Flask)の定義
web/requirements.txtには、FlaskとPostgreSQL接続に必要なライブラリを記述します。
Plaintext
# web/requirements.txt
Flask
psycopg2-binary # PostgreSQL接続用
web/app.pyでは、環境変数からデータベース接続情報を取得するように記述します。
Python
# web/app.py (抜粋)
import psycopg2
import os
# ホスト名に「db」サービス名、ポートにデフォルト値を使用
DB_HOST = os.environ.get('DB_HOST', 'db')
DB_NAME = os.environ.get('DB_NAME', 'mydatabase')
# ... 他の接続情報も環境変数から取得
# ... データベース接続チェックのロジック ...
web/Dockerfileは、Python環境のセットアップとコードコピーを行います。
Dockerfile
# web/Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app/
CMD ["python", "app.py"]
2-3. Docker Composeファイルの記述(docker-compose.yml)
これが本ハンズオンの核心です。2つのサービス(webとdb)とデータの永続化に必要なvolumesを定義します。
YAML
# docker-compose.yml
version: '3.8'
services:
# --- 1. Webアプリケーションサービス ---
web:
build: ./web # ./web フォルダの Dockerfile を参照してイメージを作成
container_name: flask_web_app
ports:
- "8000:5000" # ホスト:コンテナ
depends_on:
- db # データベースが起動するまで待機
environment:
# 環境変数を通じて、WebアプリにDB接続情報を渡す
DB_HOST: db # ★重要: サービス名「db」がホスト名になる
DB_NAME: mydatabase
DB_USER: myuser
DB_PASS: mypassword
# --- 2. データベースサービス (PostgreSQL) ---
db:
image: postgres:14-alpine # Docker Hubから軽量なイメージを使用
container_name: app_postgres_db
# データを永続化するためのボリューム設定
volumes:
- postgres_data:/var/lib/postgresql/data # 定義した名前付きボリュームを使用
environment:
# PostgreSQLイメージ独自の環境変数で初期設定を行う
POSTGRES_DB: mydatabase
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
# DBはホストに公開しない(Webサービス経由でのみアクセス)
# --- 3. データの永続化設定 ---
volumes:
postgres_data: # 名前付きボリューム。コンテナを停止・削除してもデータが残る。
3. コマンド実行:環境の一括構築と管理
docker-compose.ymlファイルがあるルートディレクトリ(docker_compose_project)で、以下のコマンドを実行します。
3-1. 環境のビルドと起動
このコマンド一つで、Webアプリイメージのビルド、PostgreSQLイメージのダウンロード、サービスの起動、ネットワークの構築が全て自動で行われます。
Bash
docker compose up -d --build
-d(detached): バックグラウンドで実行し、ターミナルを占有しません。--build: 起動前に、buildディレクティブを持つサービス(web)のイメージを再ビルドします。
3-2. 動作確認
起動後、ブラウザで http://localhost:8000 にアクセスし、「Database connection successful!」といったメッセージが表示されれば、WebアプリとDBがコンテナネットワークを通じて正常に連携していることになります。
サービスの状態を確認するには、以下のコマンドを使います。
Bash
# 起動中のサービスの状態を確認
docker compose ps
3-3. サービスの停止とクリーンアップ
開発を終える際や環境をリセットする際に使用します。
Bash
# サービスの停止とコンテナの削除 (ボリュームのデータは残る)
docker compose down
# データも完全に削除して環境をリセットする場合
docker compose down -v
docker compose down -vは、ローカルで定義した名前付きボリューム(postgres_data)も削除するため、本番環境での実行は避けるべきです。
4. Docker Composeを使いこなすための応用テクニック
Docker Composeの真価は、基本的な連携だけでなく、より高度な開発・テスト要件に対応できる柔軟性にあります。
4-1. 環境変数ファイルの活用 (.env)
機密情報(パスワードなど)や環境固有の値(ポート番号など)をdocker-compose.ymlに直接書き込むのはセキュリティ上好ましくありません。
docker-compose.ymlと同じディレクトリに.envファイルを作成し、以下の内容を記述することで、YAMLファイル内で${VARIABLE}として呼び出すことができます。
Plaintext
# .env
POSTGRES_PASSWORD=secure_password_123
WEB_PORT=8081
YAMLファイル内では以下のように利用します。
YAML
# docker-compose.yml (抜粋)
# ...
db:
# ...
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # .envから自動で読み込まれる
# ...
web:
# ...
ports:
- "${WEB_PORT}:5000" # ホストのポート番号が8081になる
4-2. 開発用と本番用の設定の分離
環境によって設定を変えたい場合、複数のComposeファイルを作成し、-fオプションで結合して使用できます。
docker-compose.yml(共通の基本設定)docker-compose.dev.yml(開発用の設定: ホットリロード、デバッグモードなど)docker-compose.prod.yml(本番用の設定: リソース制限、レプリカ数など)
Bash
# 開発環境の起動(基本設定と開発設定を結合)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
まとめ
Docker Composeは、現代のマルチサービスアプリケーション開発において欠かせないツールです。docker-compose.ymlという設定のコード化を通じて、チームの開発環境を標準化し、デプロイメントの基盤を築きます。
コメントを残す