Docker の公式 PostgreSQL イメージでの HEALTHCHECK 指定方法まとめ

Docker

Docker の公式 PostgreSQL イメージを使うときの HEALTHCHECK の指定方法についてまとめました。

Docker postgres イメージ

各種バージョン・イメージが違うとあてはまらなくなることがあるので、参考にされる際はその点留意してください。

確認時の環境

対象イメージ

macOS

❯ sw_vers
ProductName:  macOS
ProductVersion: 12.6
BuildVersion: 21G115

Docker

docker version
(省略)
Server: Docker Desktop 4.12.0 (85629)
(省略)
docker --version
Docker version 20.10.17, build 100c701
docker compose version
Docker Compose version v2.10.2

公式 PostgreSQL イメージを使うときの HEALTHCHECK の指定方法

有用なコマンド

DB が起動しているかどうかのチェックだけでよければ、シンプルな pg_isready コマンドが便利です。 DB が起動していてなおかつ操作ユーザーが作成済みなどプラスアルファの条件をチェックしたい場合は psql コマンドを使います。

コマンド 使いどころ
pg_isready DB が起動していることをチェックしたい
psql DB が起動しているプラスアルファの条件をチェックしたい

pg_isready を使う場合

先に結論ですが、最終形は次のようになります:

FROM postgres:14

HEALTHCHECK \
  --interval=2s \
  --timeout=5s \
  --retries=5 \
  CMD pg_isready -U "${POSTGRES_USER:-postgres}" || exit 1

結論に至るまでを以下順を追って説明しています。

pg_isready は引数なしで次のように使うことができます:

FROM postgres:14

HEALTHCHECK \
  --interval=2s \
  --timeout=5s \
  --retries=5 \
  CMD ["pg_isready"]

ただしこの形だと healthcheck 機能はうまく動きますが pg_isready コマンドが実行される度に次のメッセージがログに出力されるという問題があります( interval が短いとそれなりの頻度で出力されます):

role "root" does not exist

このメッセージを出さないようにするにはオプション -U--username )を使って有効な DB ユーザー名を指定する必要があります:

FROM postgres:14

HEALTHCHECK \
  --interval=2s \
  --timeout=5s \
  --retries=5 \
  CMD ["pg_isready", "-U", "postgres"]

↑ の CMD 行の末尾の postgrespostgres:14 イメージのデフォルトの DB ユーザー名です。

postgres イメージでは環境変数 POSTGRES_USER を使って DB ユーザー名を変更できるようになっているので、 POSTGRES_USER を定義してユーザー名を変更した場合は pg_isready コマンドの引数もそれにあわせる必要があります。

CMD の後の部分を ["pg_isready", "-U", "postgres"] のような配列(= exec 配列)ではなく pg_isready -U postgres のような文字列(= shell コマンド)で指定するとその中で環境変数が使えるので POSTGRES_USER もそのまま使うことができます:

FROM postgres:14

HEALTHCHECK \
  --interval=2s \
  --timeout=5s \
  --retries=5 \
  CMD pg_isready -U "${POSTGRES_USER:-postgres}"

さらに、 Docker 公式ドキュメントによると HEALTHCHECK では実行されたコマンドの終了ステータスが次のとおり解釈されるのですが……

ステータス 解釈
0 success: コンテナは健康で使用可能である
1 unhealthy: コンテナは正しく動いていない
2 reserved: (使用しないこと)

他方、 pg_isready の方は以下の終了ステータスを返すようになっています。

ステータス 意味合い
0 接続受付中
1 接続拒否中(起動中など)
2 レスポンスなし
3 リクエスト未実施(パラメータ間違いなど)

参考:

Exit Status

pg_isready returns 0 to the shell if the server is accepting connections normally, 1 if the server is rejecting connections (for example during startup), 2 if there was no response to the connection attempt, and 3 if no attempt was made (for example due to invalid parameters).

そのため、厳密に HEALTHCHECK の仕様にあわせるには || exit 1 を末尾に追加する必要があるようです:

FROM postgres:14

HEALTHCHECK \
  --interval=2s \
  --timeout=5s \
  --retries=5 \
  CMD pg_isready -U "${POSTGRES_USER:-postgres}" || exit 1

pg_isready については以上です。

psql を使う場合

基本的には pg_isready と同様です。 s-c オプションで SQL 文を渡せるので、チェックしたい条件にあった SQL 文を渡して使えば OK です:

FROM postgres:14

HEALTHCHECK \
  --interval=2s \
  --timeout=5s \
  --retries=5 \
  CMD psql -U "${POSTGRES_USER:-postgres}" -c "SELECT 1" || exit 1

こちらも末尾に || exit 1 をつけておくとよさそうです。

参考:

Exit Status

psql returns 0 to the shell if it finished normally, 1 if a fatal error of its own occurs (e.g., out of memory, file not found), 2 if the connection to the server went bad and the session was not interactive, and 3 if an error occurred in a script and the variable ON_ERROR_STOP was set.

その他参考


アバター
後藤隼人 ( ごとうはやと )

Python や PHP を使ってソフトウェア開発やウェブ制作をしています。詳しくはこちら