Composeの起動順とhealthcheck: 起動済みと準備完了は別
Composeでデータベースを先に起動しても、アプリが接続できる時刻まで待つとは限らない。Docker公式は、Composeが通常待つのはコンテナがrunningになるまでで、サービスの準備完了ではないと説明している。外部AI APIを呼ぶワークフローでは、再起動直後だけ失敗する原因になりやすい。
この違いを確認するため、次の表を公式仕様から整理した。動作結果を伴うベンチマークではない。確認日: 2026年9月12日。Docker公式: Composeの起動順と終了順
| 状態 | 何が起きているか | 依存する側を起動してよいか |
|---|---|---|
| 作成済み | コンテナ定義が作られた | まだ判断しない |
| 起動済み | プロセスが動き始めた | DB初期化中なら早すぎる |
| healthy | 定義したhealthcheckが通った | healthcheckの意味が接続可能と一致するなら候補になる |
| 完了成功 | 一回限りの初期化処理が成功終了した | 初期化を待つ依存先に使える |
depends_on は順番だけでは足りない
depends_on を書くと依存関係に沿ってサービスを作成・停止できる。しかし、単に依存先を列挙しただけでは「データベースがSQLを受けられる」状態を待たない。依存先が起動プロセスの途中なら、アプリは接続失敗を記録して終了したり、再試行の設定次第で不安定になったりする。
準備完了を待ちたい依存先には healthcheck を定義し、依存側で condition: service_healthy を選ぶ。初期スキーマ作成のように一度だけ成功終了してほしい処理には、service_completed_successfully が意味に合う場合がある。反対に、単にプロセスがいれば足りる依存先では service_started で足りる。
healthcheckは「プロセスがいるか」ではなく利用可能かを見る
healthcheckの内容が浅いと、healthyの表示に安心してしまう。HTTPサーバーなら、アプリが必要とするエンドポイントが応答するか。PostgreSQLの pg_isready はサーバーが接続を受け付けているかを調べるコマンドで、正しいユーザー名、パスワード、データベース名を与えなくても状態確認ができる。つまり、これだけではアプリ用アカウントの認証成功やSQL実行まで保証しない。依存側が必要とする条件を確認項目にする。PostgreSQL公式: pg_isready
次は既存の db サービスへ置く healthcheck と、依存側の depends_on だけを抜き出した例である。単独で起動するComposeファイルではない。イメージ、環境変数、volumeなどは採用するDBの公式手順に従って別途定義する。バージョンは、採用前に公式イメージのリリース情報と自分の互換性を確認して固定する。
# dbサービス内
healthcheck:
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 5432"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
# dbへ依存するサービス内
depends_on:
db:
condition: service_healthy
pg_isready は、使うイメージに含まれることと、待受ポートが実際の設定と一致することを確認して使う。healthcheckを通すためだけに認証を緩めたり、アプリの本来の失敗を隠したりしない。
再起動後の確認は三段に分ける
一段目では、Composeのサービスが期待した状態へ移ったかを確認する。二段目では、アプリ用アカウントで認証し、必要なテーブルへ読み書きできることを確認する。三段目で、外部へ送らないテストデータを使い、利用経路の処理を一件だけ通す。n8nなら、画面が開くことと、Webhookを受けてAI APIへの呼び出しまで成功することは別の確認になる。データベースを使うアプリなら、接続ログ、キュー、保存先も対象に含める。
確認の順番を運用メモに残すと、障害時に「コンテナは動いているのに処理が進まない」を切り分けやすい。失敗通知を扱うワークフローは、依存サービスが準備できないときの再試行回数や、二重実行の防止も設計へ入れる。
参考資料
- Docker公式: Composeの起動順と終了順(確認日: 2026年9月12日)
- PostgreSQL公式: pg_isready(確認日: 2026年9月12日)