はじめに
Dockerfileでイメージを作成し、コンテナを起動できるようになった。しかし、実際のアプリケーション開発では、Webサーバー、データベース、キャッシュサーバーなど複数のコンテナを連携させる必要があります。これらを個別のdocker runコマンドで管理するのは煩雑で、ミスも起きやすくなります。
Docker Composeは、複数のコンテナを1つの設定ファイル(compose.yaml)で定義し、一括で起動・停止できるツールです。本記事では、compose.yamlの基本構文からDocker Composeの主要コマンド、環境変数の管理方法まで体系的に解説します。この記事を読み終えると、以下のことができるようになります。
- Docker Composeの役割とメリットを理解できる
- compose.yamlでservices/volumes/networksを定義できる
- docker compose up/down/logs/execなどの主要コマンドを使いこなせる
- 環境変数を適切に管理できる
前提として、Dockerの基本コマンドとDockerfileの作成経験があることを想定しています。まだDockerの基本操作に慣れていない場合は、Docker基本コマンド完全ガイドを参照してください。
Docker Composeとは
Docker Composeは、マルチコンテナのDockerアプリケーションを定義・実行するためのツールです。YAMLファイル(compose.yaml)にアプリケーションのサービス構成を記述し、単一のコマンドで複数コンテナを一括管理できます。
なぜDocker Composeが必要なのか
複数コンテナを手動で管理する場合と、Docker Composeを使用する場合を比較してみましょう。
| 観点 | 手動管理(docker run) | Docker Compose |
|---|---|---|
| 起動コマンド | コンテナごとに個別実行 | docker compose up一発 |
| 設定の再現性 | コマンド履歴に依存 | compose.yamlで明文化 |
| コンテナ間通信 | 手動でネットワーク設定 | 自動でネットワーク作成 |
| 依存関係管理 | 起動順序を手動で制御 | depends_onで宣言的に定義 |
| チーム共有 | 手順書が必要 | compose.yamlを共有するだけ |
例えば、WebアプリケーションとMySQLデータベースを起動する場合、手動では次のようなコマンドが必要です。
|
|
Docker Composeを使えば、これらをcompose.yamlに定義し、docker compose up -dだけで起動できます。
Docker Composeのアーキテクチャ
Docker Composeの構成要素を図で理解しましょう。
flowchart TD
subgraph ComposeYaml["compose.yaml"]
services["services: コンテナ定義\n web:\n db:"]
volumes["volumes: データ永続化\n db-data:"]
networks["networks: コンテナ間通信\n backend:"]
end
ComposeYaml -->|"docker compose up"| DockerEngine
subgraph DockerEngine["Docker Engine"]
web["コンテナ: web"]
db["コンテナ: db"]
backendNetwork["ネットワーク: backend"]
dbDataVolume["ボリューム: db-data"]
web --- backendNetwork
db --- backendNetwork
db --- dbDataVolume
endcompose.yamlの基本構文
compose.yamlは、Docker Composeの設定ファイルです。かつてはdocker-compose.ymlというファイル名が使われていましたが、現在はcompose.yamlが推奨されています。
ファイル名の優先順位
Docker Composeは以下の順序でファイルを検索します。
compose.yaml(推奨)compose.ymldocker-compose.yamldocker-compose.yml
基本構造
compose.yamlのトップレベル要素は以下の4つです。
|
|
各トップレベル要素の役割は次のとおりです。
| 要素 | 説明 | 必須/オプション |
|---|---|---|
name |
プロジェクト名。コンテナ名のプレフィックスに使用 | オプション |
services |
コンテナの定義。アプリケーションの各コンポーネントを記述 | 必須 |
volumes |
名前付きボリュームの定義。データ永続化に使用 | オプション |
networks |
カスタムネットワークの定義。コンテナ間通信の制御に使用 | オプション |
シンプルなcompose.yamlの例
NginxとMySQLを使った最小構成の例を見てみましょう。
|
|
この設定でdocker compose up -dを実行すると、NginxコンテナとMySQLコンテナが起動し、自動的に同一ネットワークに接続されます。
servicesの定義方法
servicesはcompose.yamlの中核となる要素です。各サービスがDockerコンテナに対応し、コンテナの設定を詳細に定義できます。
主要な属性
サービス定義でよく使われる属性を紹介します。
image
使用するDockerイメージを指定します。
|
|
タグを省略するとlatestが使用されますが、本番環境では明示的にタグを指定することを推奨します。
build
Dockerfileからイメージをビルドする場合に使用します。
|
|
contextはビルドコンテキストのパス、dockerfileはDockerfileの名前を指定します。単純な場合は短縮形も使えます。
|
|
ports
ホストとコンテナ間のポートマッピングを定義します。
|
|
形式は"ホストポート:コンテナポート"です。YAMLでは80:80のような形式が浮動小数点数と解釈される可能性があるため、クォートで囲むことを推奨します。
environment
コンテナ内の環境変数を設定します。マップ形式とリスト形式の2つの書き方があります。
|
|
|
|
volumes
ボリュームマウントを定義します。詳細は後述の「volumesの定義方法」で解説します。
|
|
depends_on
サービスの依存関係を定義し、起動順序を制御します。
|
|
この設定では、db → app → webの順で起動します。
より厳密な制御が必要な場合は、conditionを使ってサービスの状態を指定できます。
|
|
service_healthyを指定すると、依存先サービスのヘルスチェックが成功するまで待機します。
command
コンテナ起動時に実行するコマンドを上書きします。
|
|
リスト形式でも指定できます。
|
|
restart
コンテナの再起動ポリシーを設定します。
|
|
| 値 | 説明 |
|---|---|
no |
再起動しない(デフォルト) |
always |
常に再起動 |
on-failure |
異常終了時のみ再起動 |
unless-stopped |
手動停止以外は再起動 |
実践的なサービス定義例
Webアプリケーション、API、データベースの3層構成の例です。
|
|
volumesの定義方法
volumesは、コンテナのデータを永続化するために使用します。compose.yamlでは、トップレベルでボリュームを定義し、サービス内でマウントします。
ボリュームの種類
Docker Composeで使用できるボリュームには、名前付きボリュームとバインドマウントの2種類があります。
ボリュームの種類
┌─────────────────────────────────────────────────────────────────┐
│ 名前付きボリューム │
│ │
│ ホスト コンテナ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ /var/lib/docker/ │ │ │ │
│ │ volumes/ │ ───▶ │ /var/lib/mysql │ │
│ │ db-data/ │ │ │ │
│ └────────────────────┘ └────────────────────┘ │
│ Dockerが管理 │
├─────────────────────────────────────────────────────────────────┤
│ バインドマウント │
│ │
│ ホスト コンテナ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ │ │ │ │
│ │ ./src │ ───▶ │ /app/src │ │
│ │ │ │ │ │
│ └────────────────────┘ └────────────────────┘ │
│ ユーザーが管理 │
└─────────────────────────────────────────────────────────────────┘
| 種類 | 用途 | 記法例 |
|---|---|---|
| 名前付きボリューム | データベースなどの永続データ | db-data:/var/lib/mysql |
| バインドマウント | ソースコードの同期(開発時) | ./src:/app/src |
名前付きボリュームの定義
名前付きボリュームは、トップレベルのvolumesで定義します。
|
|
ボリュームにオプションを指定することもできます。
|
|
バインドマウント
開発環境では、ホストのソースコードをコンテナにマウントして、コード変更を即座に反映させることが一般的です。
|
|
バインドマウントでは、パスが./や../で始まる場合はホストのパス、そうでない場合は名前付きボリュームとして解釈されます。
短縮形と長形式
ボリュームマウントは短縮形と長形式の2つの書き方があります。
|
|
長形式を使うと、より詳細なオプションを指定できます。
networksの定義方法
Docker Composeは、デフォルトでプロジェクト用のネットワークを自動作成します。カスタムネットワークを定義することで、サービス間の通信をより細かく制御できます。
デフォルトネットワーク
compose.yamlでnetworksを明示的に定義しない場合、Docker Composeは<プロジェクト名>_defaultという名前のブリッジネットワークを自動作成し、すべてのサービスをこのネットワークに接続します。
|
|
カスタムネットワークの定義
複数のネットワークを定義して、サービス間の通信を分離できます。
|
|
この構成では、以下のような通信制御が実現されます。
ネットワーク分離の例
┌──────────────────────────────────────────────────────────────────┐
│ │
│ ┌──────────────┐ │
│ │ frontend │ │
│ │ コンテナ │ │
│ └──────┬───────┘ │
│ │ │
│ ┌──────▼───────────────────────┐ │
│ │ frontend-net │ │
│ └──────────────────┬───────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ api │ │
│ │ コンテナ │ │
│ └────────┬────────┘ │
│ │ │
│ ┌──────────────────▼───────────┐ │
│ │ backend-net │ │
│ └──────────────────┬───────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ db │ │
│ │ コンテナ │ ← frontendからは直接アクセス不可 │
│ └─────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
frontendコンテナはapiにアクセスできますが、dbには直接アクセスできません。apiコンテナは両方のネットワークに接続されているため、frontendとdbの両方と通信できます。
ネットワークオプション
ネットワークに詳細なオプションを指定することもできます。
|
|
サービス内でのネットワーク設定
サービスごとにネットワーク接続の詳細を設定できます。
|
|
aliasesを使うと、同一ネットワーク内の他のコンテナから別名でアクセスできるようになります。
Docker Composeの主要コマンド
Docker Composeの操作に使用する主要コマンドを紹介します。現在のDocker CLIでは、docker compose(スペース区切り)が標準です。
docker compose up
コンテナを作成して起動します。最も頻繁に使用するコマンドです。
|
|
主要なオプションは以下のとおりです。
| オプション | 説明 |
|---|---|
-d, --detach |
バックグラウンドで実行 |
--build |
起動前にイメージをビルド |
--force-recreate |
コンテナを強制的に再作成 |
--no-deps |
依存サービスを起動しない |
--scale SERVICE=NUM |
サービスのインスタンス数を指定 |
docker compose down
コンテナを停止し、コンテナとネットワークを削除します。
|
|
| オプション | 説明 |
|---|---|
-v, --volumes |
名前付きボリュームも削除 |
--rmi all |
すべてのイメージを削除 |
--rmi local |
カスタムタグのないイメージのみ削除 |
--remove-orphans |
compose.yamlに定義されていないコンテナも削除 |
docker compose logs
コンテナのログを表示します。
|
|
| オプション | 説明 |
|---|---|
-f, --follow |
ログをリアルタイムでフォロー |
--tail N |
最新N行のみ表示 |
-t, --timestamps |
タイムスタンプを表示 |
--no-color |
カラー出力を無効化 |
docker compose exec
実行中のコンテナ内でコマンドを実行します。
|
|
| オプション | 説明 |
|---|---|
-d, --detach |
バックグラウンドで実行 |
-e, --env |
環境変数を設定 |
-u, --user |
実行ユーザーを指定 |
-w, --workdir |
作業ディレクトリを指定 |
docker compose ps
コンテナの状態を一覧表示します。
|
|
docker compose start / stop / restart
コンテナのライフサイクルを制御します。
|
|
stopはdownと異なり、コンテナを削除しません。設定を変更せずに一時停止したい場合に使用します。
docker compose build
イメージをビルドします。
|
|
docker compose pull / push
イメージの取得・プッシュを行います。
|
|
コマンド比較表
主要コマンドの用途をまとめます。
| コマンド | 作成 | 起動 | 停止 | 削除 | 用途 |
|---|---|---|---|---|---|
up |
Yes | Yes | - | - | 初回起動、設定変更後の再起動 |
down |
- | - | Yes | Yes | 完全停止、クリーンアップ |
start |
- | Yes | - | - | 停止中コンテナの起動 |
stop |
- | - | Yes | - | 一時停止 |
restart |
- | Yes | Yes | - | 再起動 |
環境変数の管理方法
Docker Composeでは、環境変数を柔軟に管理できます。データベースの接続情報やAPIキーなど、環境ごとに異なる設定を外部化することで、セキュリティと可搬性を向上させます。
環境変数の設定方法
1. compose.yaml内で直接指定
最もシンプルな方法ですが、機密情報には不向きです。
|
|
2. .envファイルを使用
プロジェクトルートに.envファイルを配置すると、自動的に読み込まれます。
|
|
|
|
.envファイルは.gitignoreに追加し、Gitにコミットしないようにしましょう。
3. env_fileで外部ファイルを指定
サービスごとに異なる環境変数ファイルを読み込めます。
|
|
|
|
複数ファイルを指定した場合、後から読み込まれたファイルの値が優先されます。
4. シェル環境変数を参照
ホストマシンの環境変数を参照することもできます。
|
|
|
|
環境変数の優先順位
同じ環境変数が複数箇所で定義されている場合、以下の優先順位で適用されます(上が高優先)。
docker compose run -eで指定した値- シェル環境変数
.envファイルenv_fileで指定したファイル- compose.yamlの
environmentで指定した値 - Dockerfileの
ENVで指定した値
環境別設定の管理
開発環境と本番環境で異なる設定を使う場合、複数のファイルを組み合わせます。
|
|
|
|
|
|
|
|
複数ファイルを指定して起動します。
|
|
変数のデフォルト値
環境変数が未設定の場合のデフォルト値を指定できます。
|
|
| 構文 | 説明 |
|---|---|
${VAR:-default} |
未設定の場合にdefaultを使用 |
${VAR-default} |
未設定の場合にdefaultを使用(空文字は維持) |
${VAR:?error} |
未設定の場合にエラーメッセージを表示して終了 |
${VAR?error} |
未設定の場合にエラーメッセージを表示して終了(空文字は許可) |
機密情報の管理
パスワードやAPIキーなどの機密情報は、Docker Secretsを使用することを推奨します。ただし、Docker Secretsは主にDocker Swarmモード向けの機能です。ローカル開発では、.envファイルをGit管理外にする運用が一般的です。
|
|
.env.exampleとしてテンプレートをリポジトリに含め、実際の値は各開発者がローカルで設定する方法が安全です。
|
|
実践的なcompose.yaml例
ここまで学んだ内容を活用した実践的な構成例を紹介します。
Webアプリケーション + データベース + キャッシュ
|
|
この構成のポイントは以下のとおりです。
- ネットワーク分離: frontendとbackendを分離し、nginxからdbへの直接アクセスを防止
- ヘルスチェック: dbのヘルスチェックにより、確実に起動完了を待機
- データ永続化: PostgreSQLとRedisのデータをボリュームで永続化
- 環境変数: 機密情報は.envファイルで管理
まとめ
本記事では、Docker Composeの基本からcompose.yamlの書き方、主要コマンド、環境変数の管理方法まで解説しました。
Docker Composeを使用することで、以下のメリットが得られます。
- 複数コンテナを1つのファイルで宣言的に定義できる
docker compose up一発でマルチコンテナ環境を構築できる- ネットワークやボリュームが自動的に管理される
- 環境変数の外部化により、環境ごとの設定が容易になる
次のステップとして、以下の学習をおすすめします。
- Docker Composeを使った実際のアプリケーション開発
- Docker Swarmによるオーケストレーション
- Kubernetesへの移行を見据えた設計