Compose における起動順と停止順の制御

depends_on オプションの使用で、サービスの起動順番と停止順番を制御できます。Compose は常にコンテナの依存関係の順番で、起動と停止を行います。この依存関係を決めるのは、 depends_onlinksvolumes_fromnetwork_mode: "service:..." です。

しかし、Compose の起動とは、コンテナの「準備」が整うまで(個々のアプリケーションによって、意味は異なりますが)待ちません。単にコンテナを実行するだけです。これには相応の理由があります。

(たとえば)データベースの準備が調うまで待機する問題とは、分散システムという大きな問題の一部にすぎません。本番環境では、データベースが利用不可能になったり、常にホストを移動します。アプリケーションは、このような障害に対する 回復力(resilient) が必要です。

これを扱うため、データベースで障害の発生後に、接続の再確立を試みるようアプリケーションを設計します。アプリケーションが接続を再試行すると、いずれデータベースに接続できるようにします。

起動時と、何らかの理由で通信が失われた場合の両方で、アプリケーション コード内でこの確認をするのが、一番良い解決策です。しかし、このレベルの回復力を必要としないばあい、 ラッパー スクリプト(wrapper script) で問題を回避できます。

  • ツールを使います。具体的には wait-for-itdockerizeWait4X 、 sh 互換の wait-forReadyAndContainers テンプレートです。

    たとえば、サービスのコマンドをラップする wait-for-it.shwait-for を使います。

    version: "2"
    services:
      web:
        build: .
        ports:
          - "80:8000"
        depends_on:
          - "db"
        command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
      db:
        image: postgres
    
  • 別の解決策として、自分でラッパースクリプトを書き、よりアプリケーション固有のヘルスチェックを処理できるようにします。たとえば、 Postgres でコマンドを受け付ける準備が調うまで待ちたい場合を考えます。

    #!/bin/sh
    # wait-for-postgres.sh
    
    set -e
    
    host="$1"
    shift
    
    until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c '\q'; do
      >&2 echo "Postgres is unavailable - sleeping"
      sleep 1
    done
    
    >&2 echo "Postgres is up - executing command"
    exec "$@"
    

    この例にあるラッパースクリプトを使うには、次のように設定します。

    command: ["./wait-for-postgres.sh", "db", "python", "app.py"]
    

Compose ドキュメント

参考

Control startup and shutdown order in Compose

https://docs.docker.com/compose/startup-order/