2026年9月25日
2026年9月25日
docker-compose.ymlの書き方を解説|基本構造・主要キー・WordPress構成例と書き間違いの防ぎ方
docker-compose.yml は、複数のコンテナの構成(使うイメージ、ポート、環境変数、ボリューム、起動順など)を1つのファイルにまとめる設定ファイルです。この記事では、ファイルの基本構造と主要なキーの意味を説明したうえで、WordPress と MySQL の構成例を1行ずつ読み解き、YAML でつまずきやすい書き方と、書いた内容を検証する方法を紹介します。ネットワークの詳しい仕組みは別の話題になるため、ここでは Compose での最小限の扱いにとどめます。
まず押さえたい前提: ファイル名とバージョン表記
現在の Docker Compose は、Docker CLI のサブコマンドとして動く docker compose(スペース区切り)が標準です。ハイフン付きの docker-compose は旧版の単体コマンドで、すでにサポートが終了しています(2026年10月現在)。古い記事のコマンドは、docker-compose up を docker compose up に読み替えてください。
ファイル名は compose.yaml が推奨されていますが、docker-compose.yml も引き続き読み込まれます。両方あると compose.yaml が優先されるので、どちらか一方に統一しておくと混乱しません。
また、昔のファイルの先頭にあった version: "3.8" のような行は、現在の仕様(Compose Specification)では不要です。書いてあっても動きますが、「version は廃止された属性」という警告が出ます。新しく書くファイルでは省略して構いません。
基本構造: トップレベルのキー
docker-compose.yml のトップレベルには、主に次のキーを書きます。
services: 起動するコンテナの定義。ここが本体で、ほぼ全てのファイルにあるvolumes: 名前付きボリュームの定義。データベースのデータなど、残したいデータの置き場networks: 独自ネットワークの定義。省略すると、プロジェクト用の既定ネットワークが1つ作られるsecrets/configs: パスワードや設定ファイルをコンテナへ渡す仕組みname: プロジェクト名。省略するとディレクトリ名が使われる
YAML はインデント(字下げ)で階層を表します。インデントにはスペースを使い、タブは使えません。同じ階層はスペースの数をそろえる必要があり、1つずれるだけで「キーが別の階層にある」と解釈されてエラーになります。
WordPress構成例を読み解く
WordPress と MySQL を動かす例です。イメージのタグは例なので、使うバージョンに合わせて変えてください。
services:
db:
image: mysql:8.4
restart: unless-stopped
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD is not set}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:?DB_ROOT_PASSWORD is not set}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:php8.3-apache
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "127.0.0.1:8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD is not set}
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wp-content:/var/www/html/wp-content
volumes:
db_data:
同じディレクトリに .env を置き、パスワードを書きます。値はダミーなので、実際には長いランダムな文字列にしてください。
DB_PASSWORD=change-me-long-random-string
DB_ROOT_PASSWORD=change-me-another-long-random-string
各キーの意味
- **
image**: 使うイメージとタグ。自分で作ったイメージを使うなら、代わりにbuild:で Dockerfile のある場所を指定します。 - **
restart**: コンテナが落ちたときやサーバー再起動時の扱い。unless-stoppedは手動で止めた場合を除いて再起動します。 - **
environment**: 環境変数。MYSQL_*とWORDPRESS_DB_*は、それぞれ公式イメージが初期設定に使う変数です。MySQL 側のMYSQL_*はデータディレクトリが空のとき(初回起動時)にだけ使われるため、後からパスワードを変えても既存のデータベースには反映されません。 - **
${DB_PASSWORD:?...}**:.envやシェルの環境変数から値を埋め込む書き方です。:?を付けると、値が無いときにエラーで止まり、空のパスワードで起動する事故を防げます。 - **
volumes**:db_data:/var/lib/mysqlは名前付きボリューム、./wp-content:/var/www/html/wp-contentはホストのディレクトリをそのまま見せるバインドマウントです。名前付きボリュームはトップレベルのvolumes:にも名前を書きます。 - **
healthcheckとdepends_on**:depends_onだけではコンテナの起動順しか保証されず、MySQL が接続を受け付ける前に WordPress が起動することがあります。condition: service_healthyを付けると、ヘルスチェックが成功してから WordPress を起動します。-h 127.0.0.1で TCP 接続を確認するのは、初期化中に一時的に動くサーバーを「準備完了」と誤判定しにくくするためです。 - **
ports**:ホスト側:コンテナ側の順です。127.0.0.1:を付けると、サーバー自身からしか接続できなくなります。外部に公開する場合は、前段にリバースプロキシを置いて HTTPS で受けるのが一般的です。 - **
WORDPRESS_DB_HOST: db**: 同じ Compose ファイル内のサービスは、サービス名で互いに接続できます。localhostと書くと WordPress コンテナ自身を指してしまい、接続エラーになります。
.env はパスワードを含むので、Git で管理しているなら .gitignore に入れ、リポジトリには値を空にした .env.example だけを置きます。より厳密に扱いたい場合は、トップレベルの secrets: でファイルを渡し、公式イメージが対応している *_FILE 形式の環境変数(例: WORDPRESS_DB_PASSWORD_FILE)で読み込ませる方法もあります。
つまずきやすい書き方
- ポートは引用符で囲む:
- 8080:80のように数字とコロンだけを書くと、YAML の解釈によっては意図しない値になる場合があり、公式ドキュメントでも文字列として書くことが推奨されています。"8080:80"と書く習慣にしておくと安全です。 - yes / no / on / off は引用符で: 環境変数に
yesなどを書くと真偽値と解釈されることがあります。"yes"のように文字列にします。 - リスト形式とマップ形式を混ぜない:
environmentはKEY: valueのマップ形式でも- KEY=valueのリスト形式でも書けますが、1つのキーの中で混在させるとエラーになります。 - 相対パスの基準:
./wp-contentは、コマンドを実行した場所ではなく docker-compose.yml のあるディレクトリが基準です。 - **
$を値に含めたいとき**:$は変数展開に使われるため、文字として使いたい場合は$$と書きます。
書いたら検証する
起動する前に docker compose config を実行すると、変数を展開し、構文を解釈した最終的な設定が表示されます。インデントの誤りや未定義の変数はここで見つかります。表示内容にはパスワードも展開されて出るので、画面共有やログへの貼り付けには注意してください。
docker compose config # 解釈後の設定を表示
docker compose up -d # バックグラウンドで起動
docker compose ps # 状態とヘルスチェックの結果
docker compose logs -f wordpress
docker compose ps で db が healthy になり、ブラウザで http://127.0.0.1:8080 を開いてインストール画面が出れば成功です。設定を変えたら docker compose up -d を再実行すると、変更のあったサービスだけが作り直されます。
開発用と本番用で設定を分けたい場合は、compose.override.yaml(または docker-compose.override.yml)を置くと自動で重ねて読み込まれます。本番では -f で使うファイルを明示すると、意図しない上書きを防げます。本番環境に反映する前には、データベースのバックアップを取り、ステージングで同じファイルを起動して確認してください。
まとめ
- コマンドは
docker compose、ファイル名はcompose.yaml推奨(docker-compose.ymlも可)、version:は不要 - トップレベルは
services・volumes・networks・secretsが中心。インデントはスペースで、階層をそろえる - パスワードは
.envと${VAR:?...}で渡し、.envは Git に入れない depends_onにcondition: service_healthyを組み合わせて、データベースの準備を待つ- サービス間の接続はサービス名で。ポートは引用符付きで書き、必要なら
127.0.0.1:で公開範囲を絞る - 起動前に
docker compose configで検証し、本番反映前にバックアップとステージング確認を行う