Docker ComposeでDBコンテナがrunningでも、アプリから接続できる準備が終わったとは限りません。ただし、接続拒否をすべて起動待ち不足と決めつけるのも早計です。アプリがどのhost・portへ接続しているかを確かめ、その後にDBのready状態と依存条件を確認します。
この記事は現在のDocker Composeでdocker compose upを使う構成の診断です。Swarmや古いdocker-compose、別の起動経路へ同じ待機動作を保証するものではありません。以下は架空のサービス構成で、DBやコンテナの起動・接続試験は行っていません。
目次
接続拒否と認証失敗を分ける
まずアプリのエラー本文、発生時刻、接続先のhostとport、対象Compose projectを記録します。passwordを含む接続文字列の全文やCompose設定全体をログへ貼りません。接続拒否、名前解決、timeout、DB認証、schema不在は、それぞれ確認先が異なります。
表は横にスクロールできます
| 症状 | 最初に確認する対象 | すぐには決めないこと |
|---|---|---|
| 名前を解決できない | service名・network・project | DBの起動時間 |
| 接続拒否 | host/port・listener・ready状態 | passwordだけが原因 |
| 接続timeout | 経路・network・到達性 | healthcheck追加で必ず解決 |
| DBの認証エラー | user・接続先・認証条件 | containerの起動順 |
| 接続後にtableがない | migration・初期化 | TCP待機だけで十分 |
エラーの表現はDBやdriverによって違います。コード名だけでなく、どの段階まで進んだかを読みます。失敗後にappだけを再起動すると通る場合も、起動待ちが原因の可能性を示すにとどまり、接続先やnetworkの確認を省略する証拠にはしません。
appから見たhostとcontainer portを確認する
Docker Composeのnetworking資料(新しいタブで開く)では、同じnetwork上のサービスはservice名で到達でき、サービス間通信はcontainer portを使います。hostへ公開したportとは役割が違います。
架空例でDB service名がdb、container側portが5432、host公開portが15432なら、同じCompose networkのappは通常db:5432を使う構成です。host上のツールがlocalhost:15432で接続できても、app containerの同じ文字列が正しいとは限りません。container内のlocalhostがどのnetwork namespaceを指すかを確認します。
表は横にスクロールできます
| 接続する場所 | 架空の接続先 | 確認する前提 |
|---|---|---|
| 同じnetworkのapp service | db:5432 | service名と共通network |
| Docker hostの検証ツール | localhost:15432 | port公開とbind先 |
| 別projectのapp | 構成に応じた名前とport | 共通networkなどの設計 |
固定container IPへ書き換えて一時的に通す方法を恒久修正にしません。再作成でIPが変わり得るため、service名と接続の再確立を前提にします。DBを外部公開することも、同networkの接続拒否に対する必須手順ではありません。
runningとreadyを依存条件で分ける
Composeのstartup order資料(新しいタブで開く)は、通常の起動でcontainerがrunningになるまで待っても、readyまでは待たないと説明しています。depends_onがあるだけで、DBがSQLを受け付けるまで待つとは読み替えません。
DBのhealthcheckと、app側の依存条件service_healthyを組み合わせる場合、何を健康と判定しているかが重要です。プロセスがあるだけなのか、接続を受けるのか、必要な初期化まで終わったのかで、appへ与える保証が違います。
表は横にスクロールできます
| 確認対象 | 測っている状態 | 測っていない可能性 |
|---|---|---|
| container running | processが動いている | DB接続受付 |
| DB固有のready probe | probeが確認する受付状態 | app用userの権限 |
| appと同等の最小接続 | その接続条件で応答する | migration完了・全query |
| migration完了 | 定義したschema変更の終了 | 後の切断への耐性 |
DB image内にprobeコマンドがあるか、認証の要否、interval・timeout・retries・開始猶予をDBの起動特性に合わせて決めます。secretをprobeのログへ出さず、失敗時に何が不健康だったかを判断できる形にします。固定秒数のsleepだけを「準備完了」の検査にはしません。
migrationと起動後の切断は別に扱う
DBが接続を受け付けても、アプリが必要とするschemaがあるとは限りません。migration用の一回限りのサービスを使う設計なら、正常完了を待つ条件service_completed_successfullyなど、目的に合う依存契約を公式仕様で確認します。healthcheckに重いmigrationを毎回実行させるのではなく、準備検査と状態変更を分けます。
また、起動時の待機は運用中のDB再起動に対する再接続の代わりにはなりません。接続が切れたらアプリ側が再解決・再接続できるか、再試行に上限があるか、処理途中のtransactionをどう扱うかを確認します。依存サービスの再起動連動設定があっても、すべての障害を自動回復する保証にはしません。
同じ条件で復旧を確認する
起動コマンド、Compose ファイル、profile、project、CLI版を固定し、DBログとappの接続ログを同じ時刻で照合します。upと一回限りのrunなど、違う経路の結果を同じ待機仕様として比較しません。
検証用環境では、初回起動、既存DBがある再起動、DB停止後の再接続を分けます。結果には実施した経路、health状態、appの最小読取、未確認のmigrationや復旧条件を残します。volumeの削除やDBの初期化を接続診断の近道にはせず、永続データを保ったまま確認する計画にします。
