Skip to main content

第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_healthyhealthcheckが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

✅ これでこうなります:


5) ここで詰まりやすいポイント(超重要)🧨

(A) $${POSTGRES_USER} って何その“$$”!?💸

ComposeのYAMLは ${VAR} を“ホスト側の環境変数置換”に使います。 でも healthcheck のコマンドは コンテナ内で環境変数を使いたい。 そのとき **$${...}($をエスケープ)**にして「コンテナ側に渡す」んです。 (公式の例もこの形です) (Docker Documentation)

(B) healthcheckが厳しすぎて永遠にhealthyにならない😇

  • DBは最初ちょい時間かかることがあるので、start_period を入れるのが効きます。 (Docker Documentation)
  • retriesinterval を詰めすぎると、起動直後に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) ミニ演習(達成感コース)🎮✨

  1. いったん healthcheckを消して起動してみる → APIログに接続失敗が出やすい(ECONNREFUSED とか)😇
  2. 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章は、この“待ち合わせ”を土台にして マイグレーション/初期データ投入を自動化して「初回起動が一発で完成する」世界に行きます🌱🚀