DockerComposeの起動順を制御する
開発環境でcompose.yml
を使用してると実行順を制御したくなることがある。
具体的にはDBコンテナよりAPIコンテナが先に起動するとmigrationなどがコケてつらい。
昔のワタシ
以下の公式ドキュメント(ja)にあるようにwait-for-xx.sh
を実行して制御していた。
※ サンプルの都合で昔は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 "$@"
# compose.yml version: "2" services: web: build: . ports: - "80:8000" depends_on: - "db" command: ["./wait-for-postgres.sh", "db", "python", "app.py"] db: image: postgres
最近のワタシ
healthcheck
でDBコンテナのヘルスチェックを行ってからAPIコンテナが起動するようにdepends_on
を設定しています。
# compose.yml version: "3.9" services: web: build: . ports: - "80:8000" depends_on: db: condition: service_healthy command: ["python", "app.py"] db: image: mysql environment: MYSQL_USER: myuser MYSQL_PASSWORD: mypassword healthcheck: test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD start_period: 5s interval: 5s timeout: 5s retries: 55
メリット
- ローカル固有の問題を
compose.yml
内で完結できるのが良い(shell追加とか不要) - コンテナ間の依存関係が
compose.yml
内で表現されているので分かりやすい - 起動順だけの話なら
service_healthy
+healthcheck
でなくservice_started
だけでいける
注意点
compose-spec
のversionが3.9
である必要があります(2023/05/24時点の最新)- 試してないけど
3.0 ~ 3.8
ではdepends_on
で使用するcondition
が動作しなかったとか?
- 試してないけど
最後に
実は結構前から使えてたみたいだけど公式ドキュメント(ja)は更新されてない*1っぽくて気づけなかった。
Do not turn away from English documents!
*1:compose-specのversionが"2"ってのが何よりの証拠