Dock Stay
起動順と環境を切り替える - depends_on / profiles の使い方・オプション・サンプル

起動順と環境を切り替える - depends_on / profiles

`depends_on` でサービスの起動順を制御し、`profiles` で dev / prod など環境ごとの有効化を切り替える。ただし起動順だけではアプリの準備完了を保証できないので healthcheck との組み合わせが必要になる。

概念図

depends_on / profiles diagram

構文

bash

実例

healthcheck と depends_on.condition の組み合わせ

bash
services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 10
  api:
    build: ./api
    depends_on:
      db:
        condition: service_healthy

profiles で dev 専用 / prod 専用のサービスを切り替える

bash
services:
  app:
    image: myapp
  mailhog:
    image: mailhog/mailhog
    profiles: ["dev"]
  metrics:
    image: prom/prometheus
    profiles: ["prod", "observability"]

depends_on の長所と限界

depends_on は「A の起動を B より先にしてほしい」という指定をコンテナ起動順に反映させる。

書き方には短い形式と長い形式の 2 種類があり、待機の基準が異なる。

  • 短い形式(配列): 依存先のコンテナプロセスが起動した時点で「依存満たし」とみなされる。アプリケーション側の準備完了(DB ならクエリを受け付けられる状態)までは待たない
  • 長い形式(condition 指定): condition: service_started / service_healthy / service_completed_successfully で待機条件を選べる。healthcheck と組み合わせると「受け付け可能になった」まで待てる

短い形式だけでは、Postgres が listen する前に API が接続試行して失敗する、という古典的な問題は解決しない。

解決策はアプリ側にリトライを実装するか、後述の healthcheck と condition: service_healthy を併用するかの二択になる。

いずれにしてもコンテナが「起動した」ことと「受け付け可能になった」ことは別物として扱う必要がある。

healthcheck と組み合わせる

depends_on を長い形式で書き、condition: service_healthy を指定すると、依存先の healthcheck が pass するまで起動を待機するようになる。

healthcheck はサービス自身の Dockerfile または compose.yml で定義し、pg_isreadycurl -f localhost/health など「準備完了のシグナル」として信頼できるコマンドを選ぶ。

interval を短くしすぎると CI で DB に過剰な接続負荷をかけるので、5 秒程度が目安になる。

retriesstart_period を組み合わせると、マイグレーション中など起動に時間がかかるサービスにも対応できる。

healthcheck 自体が不安定だと全体が立ち上がらなくなるため、healthcheck コマンドは十分にテストしてから採用する。

bash
services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      retries: 10
      start_period: 20s
  api:
    build: ./api
    depends_on:
      db:
        condition: service_healthy

profiles で dev / prod を切り替える

profiles は「通常は起動しないが、特定のプロファイルを指定したときだけ起動する」サービスを宣言する仕組み。

たとえば開発時にしか使わない MailHog や DynamoDB Local、本番監視系の Prometheus などに付けておくと、docker compose --profile dev up のように明示的に起動対象を切り替えられる。

どのプロファイルにも属さないサービスは常に起動対象になる。

環境ごとに別の compose.yml を用意する代わりに 1 ファイルで切り替えたいときに有効で、後述の override ファイルと目的が重なるが、「サービスの有無」を切り替えたい場合は profiles、「既存サービスの設定だけ差し替えたい」場合は override ファイルと使い分けるのがわかりやすい。

bash
services:
  app:
    image: myapp
  mailhog:
    image: mailhog/mailhog
    profiles: ["dev"]
# docker compose up              -> app だけ / only app
# docker compose --profile dev up -> app + mailhog

関連トピック