先に要点
Docker Composeは、アプリとデータベースなどの構成をファイルに書き、プロジェクト単位で起動・停止・更新するためのツールです。Dockerの別名ではなく、Dockerで動かすサービスの組合せと設定を管理する役割を持ちます。
たとえばWebアプリにMySQLとRedisを組み合わせる場合、イメージ名だけでなく、アプリがどの名前でDBへ接続するか、データをどこへ残すか、起動時に何を待つかも決める必要があります。Composeは、これらをcompose.yamlというYAMLファイルへまとめます。
この記事では、まず構成の読み方を整理し、実際に動く小さな例で「コンテナが起動した」と「接続できる」の違いを確かめます。最後に、設定変更・停止・データ削除を混同しない操作へつなげます。
Dockerfile・docker run・Composeの役割
Dockerfileは、アプリの実行環境やファイルを含むイメージを作る手順です。docker runはイメージからコンテナを作って実行するコマンドです。Composeは、使うイメージや設定、サービス間の関係を宣言して管理します。
| やりたいこと | 主に使うもの | 例 |
|---|---|---|
| アプリを含むイメージを作る | Dockerfileとビルド | ライブラリを導入し、アプリのファイルを含める |
| 1つのコンテナを試す | docker run | Redisだけを一度起動する |
| 構成を共有し、繰り返し起動する | Docker Compose | アプリ・DB・キャッシュの設定を一緒に管理する |
「コンテナが1つならDockerfile、複数ならCompose」という二者択一ではありません。ComposeからDockerfileを使ってビルドすることも、既存イメージだけを使うこともできます。サービスが1つでも、長い実行オプションをファイルで管理したいならComposeが役立ちます。
チームで共有する利点も、単にコマンドを短くすることではありません。ポートや保存先を差分で確認できるため、「どの設定が違うのか」を調べやすくなります。
外部サービス、秘密情報、CPUの種類などまで同じになるわけではなく、構成ファイルだけで全環境の一致を保証するものではありません。
compose.yamlで最初に読む項目
サービスは「アプリ」「DB」など、構成内の役割を表す単位です。サービス名は後述の接続先にも使います。
| 項目 | 読むときの疑問 |
|---|---|
| services | どの役割を動かすか |
| image / build | 既存イメージを使うか、手元のDockerfileから作るか |
| command / entrypoint | コンテナで何を実行するか |
| environment | アプリへどの設定値を渡すか |
| ports | ホスト側へどのポートを公開するか |
| volumes | コンテナを作り直しても残すデータは何か |
| depends_on / healthcheck | 起動時に何を、どの条件まで待つか |
実際のパスワードや接続用の秘密情報を、共有するファイルへ直接書いて公開しないでください。また、docker compose configは設定の確認に便利ですが、展開された環境変数などを含む出力をそのまま公開してはいけません。構文だけを確認するときはdocker compose config --quietを使えます。
起動順と準備完了の違いを、動かして確かめる
依存サービスを起動しても、その内部で初期化が続いていることがあります。短いリスト形式のdepends_onやcondition: service_startedは、この準備完了を待つ条件ではありません。
2026年9月21日、Docker Compose v5.5.1とRedis 8.2.9(redis:8.2-alpine)で以下の構成を確認しました。これは検証に使った版の記録です。Redisサーバーの開始を意図的に8秒遅らせ、別コンテナから接続します。
8秒は失敗を観察するための待ち時間であり、RedisやDBの通常の起動時間ではありません。
検証専用のファイルを用意する
Dockerが使える環境で、空の検証用ディレクトリに次をcompose.yamlとして保存します。docker compose ls -aでnotes-ready-demoというプロジェクトがないことを確認してください。既にある場合は削除せず、以下すべての-pの名前を別名に変えます。
services:
redis:
image: redis:8.2-alpine
mem_limit: 128m
cpus: 0.5
entrypoint: ["sh", "-c", "sleep 8; exec redis-server --save \"\" --appendonly no"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 1s
retries: 20
probe:
image: redis:8.2-alpine
mem_limit: 64m
cpus: 0.5
depends_on:
redis:
condition: service_started
command: ["redis-cli", "-h", "redis", "ping"]
networks:
default:
internal: true
redisは応答するサーバー、probeは一度だけ接続を試して終了する確認用サービスです。portsを指定せず、外部向け通信を持たない専用ネットワークでサービス同士を接続します。保存も無効にしており、この例のデータは残しません。資源上限は小さな実験のための値で、本番への推奨値ではありません。
イメージ取得はホスト側で行います。以下は保存先ディレクトリで、PowerShellまたはBashから実行するコマンドです。
docker pull redis:8.2-alpine
docker compose -p notes-ready-demo config --quiet
docker compose -p notes-ready-demo up --abort-on-container-exit --exit-code-from probe
--abort-on-container-exitは、確認用サービスの終了時に他のサービスも止めます。--exit-code-from probeは、その成否をComposeコマンドの終了コードとして返します。この指定は今回の実験用であり、常駐するアプリの通常起動に必須ではありません。
検証ではprobeが終了コード1で終わり、ログには次が出ました。
Could not connect to Redis at redis:6379: Connection refused
確認には次を使います。終了したサービスも見るため、psには-aを付けます。
docker compose -p notes-ready-demo ps -a
docker compose -p notes-ready-demo logs --no-log-prefix probe
この失敗は、サービス名redisで到達した先が、まだ接続を受け付けていないことによるものです。
実際のアプリで同じメッセージが出た場合は、接続先・ポート・サービスの異常終了なども候補になるため、メッセージだけで起動待ち不足と断定しません。
healthyを待つ条件へ変える
まず検証用コンテナとネットワークを削除します。今回の構成には保持するデータがありません。他のプロジェクトで同じ操作をする前には、コンテナ内だけに残っているデータがないか確認が必要です。
docker compose -p notes-ready-demo down
ファイル内のcondition: service_startedをcondition: service_healthyへ変更し、同じupコマンドを実行します。
docker compose -p notes-ready-demo config --quiet
docker compose -p notes-ready-demo up --abort-on-container-exit --exit-code-from probe
docker compose -p notes-ready-demo logs --no-log-prefix probe
今度はヘルスチェックが成功してからprobeが起動し、検証では終了コード0、ログは次の結果になりました。
PONG
確認が終わったら、もう一度docker compose -p notes-ready-demo downでこの検証環境を片付けます。
healthyが保証するのは、チェックした範囲まで
今回のヘルスチェックはRedisがPINGへ応答することを確認しています。アプリの認証情報、必要なデータ、業務処理の成功は確認していません。DBでも同様に、接続を受け付けることと、アプリが使うテーブルや権限が準備できていることは別です。
| 設定 | 意味 | 調整の考え方 |
|---|---|---|
| test | 健全性を判定するコマンド | アプリが待つ必要のある状態を調べられるか |
| interval | チェック間隔 | 検出の早さと実行負荷の釣合い |
| timeout | 1回のチェックの制限時間 | 正常時の所要時間を踏まえて決める |
| retries | unhealthy判定に至る連続失敗回数 | 一時的な遅延と持続する異常を分ける |
| start_period | 起動直後の失敗を回数に含めない猶予 | 初期化に必要な時間を測って設定する |
start_period は「必ず待つ秒数」ではない
start_periodは、その秒数だけ必ず待機する設定ではありません。期間内でもチェックが成功すれば準備完了として扱われます。DBの種類だけを見て一律に30秒などと決めず、初回作成と既存データからの起動を分けて観察します。
また、service_healthyは起動時の待ち合わせです。稼働後にDBが停止したり、通信が切れたりする問題まで解消しません。アプリ側にも接続の再確立や、処理内容に応じた再試行を設計します。書込み処理の再試行では、結果が不明なまま二重実行しないよう冪等性も検討します。
restart: true の範囲
depends_onの詳細設定にあるrestart: trueは、明示的なCompose操作による依存先の更新・再起動に関連する設定です。DBがクラッシュして自動再起動したときまで、依存アプリが必ず再起動されるという意味ではありません。
接続先とポートを混同しない
コンテナ同士
サービス名で接続する
例のprobeは、同じネットワーク上のサービス名redisと、Redisが待ち受けるポートを使います。
ホストのブラウザーから
ports で公開する
たとえば127.0.0.1:8081:80のようなportsを使います。この例はホストのループバックアドレスの8081番から、コンテナの80番へつなぐ指定です。上のRedis実験には追加しません。
localhost は接続元コンテナ自身を指す
別コンテナへ接続するときにlocalhostを指定すると、原則として接続元コンテナ自身を指します。コンテナ同士の通信のためだけに、DBのポートをホストへ公開する必要はありません。
プロジェクト名を-pで分けると、通常のネットワークやコンテナの名前を分離できます。ただし、ホスト側の同じIP・同じポートを二つのプロジェクトが同時に使う競合は解消しません。別の未使用ポートに変えるか、不要な公開を外します。
停止・更新・削除は、データへの影響で選ぶ
通常の常駐サービスはdocker compose up -dで起動します。操作を選ぶ際は、「止めたいだけか」「設定を変えたか」「保存データも消すのか」を先に分けます。
| 操作 | コンテナへの主な作用 | 注意点 |
|---|---|---|
| stop / start | 既存コンテナの停止・再開 | 設定変更の反映とは別 |
| restart | 既存コンテナの再起動 | compose.yamlの環境変数変更などは反映されない |
| up -d | 必要に応じて作成・再作成して起動 | イメージを作り直す場合はビルドも必要 |
| down | コンテナと管理対象ネットワークを削除 | コンテナの書込み領域も失う |
| down -v | 対象ボリュームも削除 | 名前付きボリューム等の保存データを失う |
downは単なる停止ではありません。通常、Composeで宣言した名前付きボリュームはdownだけなら残りますが、ボリュームの外へ書いたファイルはコンテナ削除で失われます。
down -v はデータの初期化を意図するときだけ
down -vはデータの初期化を意図するときだけ、対象プロジェクトと保存先、必要なバックアップを確認して使います。外部ボリュームやホストのディレクトリは削除対象が異なるため、すべてのデータを消す万能コマンドとも考えないでください。
コンテナの再作成とデータの残り方は、Dockerの停止・削除・再作成の実験で詳しく確認できます。保存先が残ることと復旧できることは別なので、本番ではバックアップと復元確認も必要です。
Docker Composeに関するよくある質問
Q. 本番でもComposeを使えますか?
A. 単一サーバーで構成を管理する選択肢になります。ただし、監視・バックアップ・更新時の停止・障害からの復旧は別途設計します。複数ホストへの配置や自動的な障害切替が必要なら、それを担う仕組みも必要です。小規模サービスでComposeを本番利用する判断を参照してください。
Q. Dev Containersと同じものですか?
A. Composeはサービス構成を管理します。Dev Containersはエディターなどから使う開発環境を定義する仕組みで、Composeの構成を利用することもできます。Dev Containersの基本で関係を整理しています。
Q. 開発用と本番用の設定は分けられますか?
A. 複数ファイルを-fで指定して設定を重ねられます。ただし、項目によって置換・追加の規則が違います。開発用のポートやマウントが残っていないか、実際に使うファイルの組合せをdocker compose configで確認します。秘密情報を含む出力の取扱いにも注意してください。
まとめ
Composeで管理するのは、コンテナの個数だけでなく、サービス間の接続・保存先・起動条件を含む構成です。まず構成を読めるようにし、起動した後はps -aとログで、常駐するサービスと役目を終えたサービスを見分けます。
今回の実験では、同じ構成でも起動待ちの条件を変えると接続結果が変わりました。ヘルスチェックで確認している範囲を理解し、運用中の再接続やデータ保護は別に設計することが、実際のアプリへ応用する際の要点です。
参考情報
2026年9月21日に公式仕様を確認しました。実験は起動条件による接続可否の比較であり、DBの初期化・本番運用・性能を検証したものではありません。