第14章:起動順と待ち合わせ(healthcheck / depends_on)⏳🩺
「APIコンテナ起動した!……あれ?DBにつながらなくて落ちた😇」 これ、Composeあるあるです。
この章では “起動順” と “準備完了(Ready)” を分けて、落ちない起動を作ります💪✨
ポイントは depends_on(順番)+healthcheck(準備完了判定) のセットです。 (Docker Documentation)
1) まず大事:depends_on だけだと「順番」しか保証しない🚦
Composeは依存関係の順でサービスを作ります(DB→APIみたいに)🧱→🧑💻 でも、コンテナが起動して“動いてるっぽい”だけで、DBが“接続受付OK”とは限らないんですね😵💫 (Docker Documentation)
だから「順番」だけじゃなくて、**“使える状態になるまで待つ”**を仕組みにします⏳✨
2) depends_on は2種類:短い書き方 / 長い書き方✍️
短い書き方(short syntax):順番だけ
services:
api:
depends_on:
- db
- redis
長い書き方(long syntax):待ち条件を付けられる(これが本命🔥)
condition は3種類あります: (Docker Documentation)
service_started:起動したらOK(短い書き方と同等)service_healthy:healthcheckがhealthyになったらOK 🩺service_completed_successfully:ジョブが成功終了したらOK(第15章の伏線🌱)
さらに、長い書き方には restart: true もあります。
「DBをCompose操作で再起動したら、APIも一緒に再起動してつなぎ直す」みたいな、地味に強い安心機能です🔁 (Docker Documentation)
3) healthcheck って何?🩺(“生きてる”じゃなく“使える”を判定)
healthcheck は コンテナの中でコマンドを実行して、成功したら healthy、失敗したら unhealthy にする仕組みです。 (Docker Documentation)
よく使う設定はこんな感じ👇 (Docker Documentation)
test:チェックコマンド(配列 or 文字列)interval:何秒ごとに試す?timeout:何秒で諦める?retries:何回失敗したらunhealthy?start_period:起動直後の猶予(DB系は重要!)start_interval:start_period中だけ細かく試す(対応Composeなら便利) (Docker Documentation)
4) 実戦テンプレ:Postgresが“ready”になるまでAPIを待たせる🐘➡️🧑💻
ここからは、そのまま教材の型として使える例です✨
Postgresは pg_isready が使えるので、これで“接続受付OK”を見ます。 (Docker Documentation)
services:
api:
build: .
depends_on:
db:
condition: service_healthy
restart: true
redis:
condition: service_started
environment:
DATABASE_URL: postgres://app:pass@db:5432/appdb
REDIS_URL: redis://redis:6379
db:
image: postgres:18
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: pass
POSTGRES_DB: appdb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
redis:
image: redis
✅ これでこうなります:
- Composeは db→redis→api の順に作る (Docker Documentation)
- さらに
apiは db がhealthyになるまで起動を待つ (Docker Documentation)
5) ここで詰まりやすいポイント(超重要)🧨
(A) $${POSTGRES_USER} って何その“$$”!?💸
ComposeのYAMLは ${VAR} を“ホスト側の環境変数置換”に使います。
でも healthcheck のコマンドは コンテナ内で環境変数を使いたい。
そのとき **$${...}($をエスケープ)**にして「コンテナ側に渡す」んです。
(公式の例もこの形です) (Docker Documentation)
(B) healthcheckが厳しすぎて永遠にhealthyにならない😇
- DBは最初ちょい時間かかることがあるので、
start_periodを入れるのが効きます。 (Docker Documentation) retriesやintervalを詰めすぎると、起動直後にunhealthyになりやすいので注意⚠️
(C) curl が無くてhealthcheck失敗(API/管理UIでありがち)
healthcheck.test は「コンテナの中で動くコマンド」なので、
そのイメージに curl が入ってないと即死します😂
DBなら pg_isready、HTTPなら wget/node で代替する、など “存在するコマンド” を選ぶのがコツです。 (Docker Documentation)
(D) Swarmの docker stack deploy とは別モノ⚠️
この章は docker compose up 前提の話。
(Swarmを使うと depends_on の扱いが違ってハマるので、ここでは気にしなくてOK🙆♂️)
6) 動作確認コマンド(“待ててるか”を目で見る)👀🧰
PowerShell / Windows Terminal でOK👇
docker compose up -d
docker compose ps
docker compose logs -f api
docker compose ps の表示で、DBが healthy っぽい状態になってからAPIが動き出すのが見えたら勝ち🏆✨
さらに「restart: true の効き」を試すなら👇(ちょっと楽しい😆)
docker compose restart db
docker compose logs -f api
DBをCompose操作で再起動したとき、APIも連動して再起動してくれたらOKです🔁 (Docker Documentation)
7) ミニ演習(達成感コース)🎮✨
- いったん healthcheckを消して起動してみる
→ APIログに接続失敗が出やすい(
ECONNREFUSEDとか)😇 - healthcheck+
service_healthyを入れて起動 → 落ちなくなる(“手順”じゃなく“仕組み”で勝つ)🎉
8) AIに頼むときの“良い投げ方”🤖💡(レビュー必須!)
たとえばこう投げると、かなり使える叩き台が返りやすいです👇
- 「postgres + redis + node api の compose.yaml を作って。db は pg_isready の healthcheck、api は service_healthy で待つ。start_period も入れて」
- 「healthcheck の test がそのイメージで確実に動くコマンドかも確認して」
最後に人間が見るポイントはこれだけ✅
healthcheck.testは本当に存在するコマンド?start_periodが適切?$${...}のエスケープを忘れてない? (Docker Documentation)
次の第15章は、この“待ち合わせ”を土台にして マイグレーション/初期データ投入を自動化して「初回起動が一発で完成する」世界に行きます🌱🚀