Compose の起動順番を制御

depends_on オプションを使えば、サービスの起動順番を制御できます。Compose は常に依存関係に従ってコンテナを起動しようとします。依存関係とは、 depends_onlinksvolumes_formnetwork_mode: "サービス:..." を指定している場合です。

しかしながら、Compose はコンテナの準備が「整う」まで待ちません(つまり、特定のアプリケーションが利用可能になるまで待ちません)。単に起動するだけです。これには理由があります。

たとえば、データベースの準備が整うまで待つのであれば、そのことが分散システム全体に対する大きな問題になり得ます。プロダクションでは、データベースは利用不可能になったり、あるいは別のホストに移動したりする場合があるでしょう。アプリケーションは、障害発生に対して復旧する必要があるためです。

データベースに対する接続が失敗したら、アプリケーションは再接続を試みるように扱わなくてはいけません。アプリケーションは再接続を試みるため、データベースへの接続を定期的に行う必要があるでしょう。

この問題を解決するベストな方法は、アプリケーションのコード上で解決することです。起動時に、あるいは何らかの理由によって接続できない場合にです。しかしながら、このレベルの復旧が必要なければ、ラッパー用のスクリプトを書くことでも対処できます。

  • wait-for-itdockerize のようなツールを使います。これらはラッパー用のスクリプトであり、アプリケーションのイメージに含めることができます。また特定のホスト側のポートに対して、TCP 接続を受け入れ可能です。

アプリケーションのイメージに適用するためには、Dockerfile の CMD 命令でラップできるように docker-compose.yml の entrypoint を設定します。

version: "2"
services:
  web:
    build: .
    ports:
      - "80:8000"
    depends_on:
      - "db"
    entrypoint: ./wait-for-it.sh db:5432
  db:
    image: postgres
  • アプリケーションが独自にヘルスチェックを行えるよう、スクリプトをラッパーすることも可能です。たとえば、Postgres コマンドが使えるようになるまで待ちたい場合を考えてみましょう。
#!/bin/bash

set -e

host="$1"
shift
cmd="$@"

until psql -h "$host" -U "postgres" -c '\l'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec $cmd

このラッパー・スクリプトの例を使うには、 entrypoint: ./wait-for-postgres.sh db と指定します。