2026年10月6日
2026年10月6日
Docker Composeで開発・ステージング・本番の複数環境を切り替える方法|overrideファイル・.env・profilesの使い分け
Docker Compose で環境ごとに設定を変えるには、共通部分を compose.yaml に置き、環境ごとの差分だけを別ファイルに書いて -f で重ねる方法が基本です。値だけが違うなら .env(--env-file)、特定の環境でだけ動かすサービスがあるなら profiles を使います。この記事では、この3つの使い分けと、合成結果の確かめ方、本番で事故を起こしやすい点を WordPress の構成を例に説明します。
前提は Docker Compose v2(docker compose コマンド)です。一部の機能は比較的新しい版で追加されたものなので、docker compose version で手元の版を確かめてから使ってください(2026年10月現在)。
3つの仕組みの使い分け
環境ごとの違いは、おおむね次の3種類に分けられます。
- 値が違う(DB 名、ドメイン、ポート番号、イメージのタグ)→ 変数展開と
.env/--env-file - 構成が違う(開発ではソースをバインドマウント、本番では使わない。本番だけリソース制限を付ける)→ override ファイルを
-fで重ねる - 動かすサービスが違う(開発だけメール確認用のツールや phpMyAdmin を動かす)→
profiles
1つの仕組みですべてを解決しようとすると、ファイルが読みにくくなります。差分の種類ごとに道具を選ぶのが、長く保守できる構成のこつです。
override ファイルを重ねる
既定の読み込み
docker compose up を引数なしで実行すると、Compose はプロジェクトディレクトリの compose.yaml と、あれば compose.override.yaml を自動で読み込んで合成します(旧来の docker-compose.yml / docker-compose.override.yml の名前も読み込まれます)。これを利用し、compose.override.yaml を開発用の差分にしておくと、開発者は何も意識せずに開発用構成で起動できます。
# compose.yaml(全環境で共通)
services:
wordpress:
image: wordpress:${WP_TAG:-latest}
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${DB_NAME}
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.4
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 --silent"]
interval: 5s
retries: 10
start_period: 30s
volumes:
db_data:
# compose.override.yaml(開発用。自動で読み込まれる)
services:
wordpress:
ports:
- "8080:80"
environment:
WORDPRESS_DEBUG: "1"
volumes:
- ./wp-content/themes/my-theme:/var/www/html/wp-content/themes/my-theme
本番用ファイルを明示して重ねる
本番やステージングでは、-f で読み込むファイルを明示します。-f を指定すると compose.override.yaml は自動では読まれないため、開発用のバインドマウントが本番に混ざることを防げます。
# compose.prod.yaml
services:
wordpress:
image: registry.example.com/my-wp:${APP_VERSION}
restart: unless-stopped
deploy:
resources:
limits:
memory: 1g
db:
restart: unless-stopped
docker compose -f compose.yaml -f compose.prod.yaml --env-file .env.prod up -d
後に指定したファイルほど優先されます。毎回長いコマンドを打つのが手間なら、環境変数 COMPOSE_FILE にファイルの一覧を入れておく方法もあります(区切り文字は Linux/macOS では :、Windows では ;)。
合成のルールでつまずく点
override の合成は「すべて上書き」ではありません。image や command のような単一の値は後のファイルで置き換わりますが、ports のようなリストは連結され、environment や volumes はキーやマウント先ごとに合成されます。そのため「本番ではポート公開をやめたい」と思って override に書いても、共通ファイルにある ports は消えません。
対策は2つあります。1つは、環境で変わる項目(ports など)を共通ファイルに書かず、各環境のファイルにだけ書くことです。もう1つは、新しめの Compose で使える !reset タグで値を空にする方法です。
services:
wordpress:
ports: !reset []
!reset やリストをまるごと置き換える !override が使えるかは版によるため、使う前に docker compose config で結果を確かめてください。
.env と --env-file で値を切り替える
Compose の ${DB_NAME} のような記述は、起動時に変数展開されます。値の出どころは、シェルの環境変数と、プロジェクトディレクトリの .env ファイル(または --env-file で指定したファイル)です。
# .env.staging の例(実際の値は各自で設定し、Git には含めない)
COMPOSE_PROJECT_NAME=mysite-staging
WP_TAG=6-php8.3-apache
DB_NAME=wp_staging
DB_USER=wpuser
DB_PASSWORD=change-me
DB_ROOT_PASSWORD=change-me-too
混同しやすいのが、サービスの env_file: 属性です。こちらはコンテナの中に渡す環境変数のファイルで、compose.yaml の ${...} の展開には使われません。「.env は Compose ファイルを組み立てるための値」「env_file: はアプリに渡す値」と覚えておくと整理しやすくなります。
必須の値は ${DB_PASSWORD:?DB_PASSWORDを設定してください} のように書くと、未設定のまま起動しようとしたときにエラーで止められます。空のパスワードで DB が初期化される事故を防げるので、本番用の変数には付けておくと安心です。
profiles で環境ごとのサービスを出し分ける
開発でだけ使うツールは、profiles を付けておくと通常の up では起動しません。
services:
phpmyadmin:
image: phpmyadmin:latest
profiles: ["dev-tools"]
ports:
- "8081:80"
environment:
PMA_HOST: db
docker compose --profile dev-tools up -d
環境変数 COMPOSE_PROFILES=dev-tools でも同じ指定ができます。phpMyAdmin のような管理ツールは、本番サーバーで外部から届く状態にしないでください。
同じサーバーで複数環境を動かすとき
1台のサーバーでステージングと本番を並べる場合、プロジェクト名を分けることが欠かせません。Compose はプロジェクト名をコンテナ名・ネットワーク名・ボリューム名の接頭辞に使うため、同じディレクトリ名のまま起動すると、別環境のつもりで同じボリュームを共有してしまうことがあります。-p オプション、COMPOSE_PROJECT_NAME、または compose.yaml の最上位の name: で明示してください。公開ポートの番号も環境ごとに重ならないようにします。
合成結果を確かめる
本番に適用する前に、実際に使われる設定を表示して確かめます。
docker compose -f compose.yaml -f compose.prod.yaml --env-file .env.prod config
変数が展開された最終的な内容が出るので、バインドマウントが残っていないか、ポートが意図どおりか、イメージのタグが正しいかを目で確認できます。出力にはパスワードなどの値も含まれるため、ログやチャットにそのまま貼らないよう注意してください。
本番で気をつけること
.env.prodなどの秘密情報を含むファイルは Git に入れず、.env.exampleに項目名だけを残す- パスワードは環境変数より Compose の
secretsで渡せるイメージなら、そちらを検討する(公式 MySQL / WordPress イメージは_FILEで終わる変数でファイルから読む方式に対応) - 本番用ファイルの変更は、まずステージングで同じコマンドを実行して確かめる
- DB のボリュームを含む変更の前には、
mysqldumpなどでバックアップを取る
まとめ
- 共通設定は
compose.yaml、環境ごとの差分は override ファイルにし、本番は-fで明示して重ねる portsなどのリストは連結されるので、環境で変わる項目は共通ファイルに書かない.env/--env-fileは Compose ファイルの変数展開用、env_file:はコンテナに渡す値で、役割が違う- 開発専用のサービスは
profilesで出し分ける - 同じサーバーで複数環境を動かすならプロジェクト名を分ける
- 適用前に
docker compose configで合成結果を確かめる