初めに
Docker(Docker Compose)でポスグレを構築したい時、別で立てているアプリケーションのコンテナなどからアクセスする場合にDocker Composeのhealthcheck機能で待機すると思います。
この際、ネットで調べて出てくるヘルスチェックの方法(コマンド)は恐らく以下の2種です。
- pg_isreadyを使う
- psqlを使う
複雑なことをするならpsqlを使用したシェルスクリプトを作りますが、今回は簡単にpg_isreadyを使用する方法で。
最終的な設定
services:
workspace:
# 待機する側のコンテナ
image: busybox
tty: true
stdin_open: true
depends_on:
# これで"local_db"のhealthcheckが成功するまで開始を待つ
local_db:
condition: service_healthy
local_db:
image: postgres:14
environment:
POSTGRES_DB: local_db
POSTGRES_USER: local_user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
volumes:
# データの永続化
- db_volume:/var/lib/postgresql/data
healthcheck:
# 実行するコマンド。ここがすべて!
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB} || exit 1"]
interval: 10s
timeout: 10s
retries: 5
start_period: 5s
volumes:
db_volume:
コメントで記載している通り、"local_db"のhealthcheckのtestに記載されたコマンドの内容がこの記事の主題です。
ダメだったパターン集
ポスグレのコンテナにヘルスチェックを行うコマンドの例はネットで調べるといくつか出てくるんですが、うまくいかなかったり、うまくいったようでエラーっぽいログは出ていたりと微妙な感じでした。
ただの"pg_isready"だけ
公式でまっさきに出てくるこの設定だと、
test: ["CMD-SHELL", "pg_isready"]
以下のようにrootというロール?は無いですよとのことでエラーになります。
2024-07-15 09:13:09.621 UTC [39] FATAL: role "root" does not exist
ユーザー名も指定
また、よく出てくるこの設定ですと、
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} || exit 1"]
以下のように接続先DBがなぜかユーザー名と同じになるらしく、エラーログが出てしまいます。
2024-07-15 09:11:08.364 UTC [39] FATAL: database "local_user" does not exist
"CMD"で実行
先に紹介した成功パターンのコマンドでも、"CMD"で実行するとうまくいきません。
test: ["CMD", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB} || exit 1"]
結果。ヘルスチェックのログを確認。
以下のコマンドはjqを実行可能である必要があります。
docker inspect --format "{{json .State.Health }}" <container name> | jq
{
"Start": "2024-07-15T09:20:14.587660971Z",
"End": "2024-07-15T09:20:14.618478886Z",
"ExitCode": -1,
"Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB} || exit 1\": executable file not found in $PATH: unknown"
}
理由はよく調べてません…(CDMとCMD-SHELLの違いわかってない)
おわりに
というわけで結論としては冒頭に書いたようなyamlとなります。
とにかくコマンドがこれじゃないと正しく動かないだけなので、ヘルスチェックの他の項目であるintervalとかretriesについては各自の都合いい感じで設定してください。
公式や他の記事がうまくいかないのは、ポスグレのバージョンが13以前だとうまくいくのかな…