🐳

Docker compose でPostgreSQLをサービスに入れたときのヘルスチェック方法

に公開

2023/01/31に書いていたスクラップを改めて記事化したものです(当時の情報ベースです)

Docker composeで、DBコンテナにPostgreSQLを使っていると、初回起動時のあれこれで時間がかかってなかなかAPPコンテナから接続できる状態になるまで時間がかかること、ありませんか?(ありました)

APPコンテナの初期化処理に、DB接続依存部分があると、うまくいかず中途半端なことになってしまうことありませんか?(ありました)

APPはDjangoだったので、Pythonで以下のスクリプトを用意し、APPコンテナの起動時に実行されるスクリプトでDBの起動を待つ仕組みを挟んでいました。

wait-for-db-up.py
""" Wating until databse server up """
import os
import sys
import time
import urllib.parse
import psycopg2

database_url = os.getenv('DATABASE_URL')

if not database_url:
    sys.exit(1)

parsed_params = urllib.parse.urlparse(database_url)
username = parsed_params.username
password = parsed_params.password
database = parsed_params.path[1:]
hostname = parsed_params.hostname

retry_count = 0
while retry_count < 300:
    try:
        connection = psycopg2.connect(host=hostname, database=database,
                                      user=username, password=password)
        connection.get_backend_pid()
        connection.close()
        sys.exit(0)
    except psycopg2.OperationalError as e:
        retry_count += 1
        print(e)
    time.sleep(1)
    print('Retry ...')

print('Over retry limit')
sys.exit(1)

それでもどうもうまくいかないときがたまにあったので、どうしたものかと思っていたところ。もっとシンプルな方法があることがわかりました。

以下の設定を、DBコンテナの方に加え、

docker-compose.yaml
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 10

依存するAPPコンテナには、以下の設定を加えればよいということがわかりました。

docker-compose.yaml
    depends_on:
      db:
        condition: service_healthy

参考

https://gotohayato.com/content/562/

Discussion