

DockerのHEALTHCHECKでnginxとphp-fpmの生死を判定する
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
DockerのHEALTHCHECK命令にはいくつかオプションがあって、意味を理解しないまま--interval=10s --timeout=3s --retries=3をコピペしてる人が多い気がする(自分もそうだった)。一回ちゃんと整理して、nginxとphp-fpmそれぞれで実際に組んでみた。
HEALTHCHECKのオプション
HEALTHCHECK --interval=10s --timeout=3s --retries=3 \ CMD <command>| オプション | 意味 |
|---|---|
--interval |
ヘルスチェックを実行する間隔(秒) |
--timeout |
1回のチェックがこの時間内に終わらないと失敗扱いになる |
--retries |
何回連続で失敗したらunhealthyにするか |
--start-period |
コンテナ起動直後の猶予期間。ここでの失敗は--retriesのカウントに含まれない(今回のDockerfileでは未使用) |
--start-periodを付けていない場合、起動が遅いアプリだと立ち上がりきる前にunhealthy判定を食らうことがあるので、起動に時間がかかるプロセスでは意識しておいた方がいい。
nginxの場合
curlで自前のヘルスチェック用エンドポイントを叩くだけ。
################################################################################# Health check #################################################################################
RUN apk add --no-cache curl
HEALTHCHECK --interval=10s --timeout=3s --retries=3 \ CMD curl -f http://localhost/hc || exit 1/hcは200を返すだけの適当なエンドポイントを用意しておけばいい。curlが失敗(非2xx)するとexit 1になってunhealthyにカウントされる。
php-fpmの場合
php-fpmは単体だとHTTPを喋らないので、curlは使えない。php-fpm自体が持ってるpingモジュールをFastCGI経由で叩く。
まずpool設定でpingを有効化する。
; /usr/local/etc/php-fpm.d/zzz-app.confping.path = /pingそのうえでDockerfile側はこう。
################################################################################# Health check #################################################################################
RUN apk add --no-cache fcgi
HEALTHCHECK --interval=10s --timeout=3s \ CMD \ SCRIPT_NAME=/ping \ SCRIPT_FILENAME=/ping \ REQUEST_METHOD=GET \ cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1cgi-fcgiでFastCGIソケット(127.0.0.1:9000)に直接繋いで、ping.pathで設定したパスを叩く。php-fpmが生きていればpongが返ってくる。curlみたいにHTTPサーバー越しじゃなくて、php-fpmプロセスそのものの生死を見れるのがポイント。
動作確認
$ docker run -itd php-fpm:healthcheck$ docker psCONTAINER ID IMAGE COMMAND STATUS PORTS NAMES877b31bf9f6a php-fpm:healthcheck ... Up 3 seconds (health: starting) 9000/tcp pensive_ramanujan数秒待つとhealth: startingからhealthyに変わる。
$ docker psCONTAINER ID IMAGE COMMAND STATUS PORTS NAMES877b31bf9f6a php-fpm:healthcheck ... Up 13 seconds (healthy) 9000/tcp pensive_ramanujan詳細なログはdocker inspectで見れる。
$ docker inspect --format='{{json .State.Health}}' <container_id> | jq{ "Status": "healthy", "FailingStreak": 0, "Log": [ { "Start": "2020-06-05T00:38:54Z", "End": "2020-06-05T00:38:54Z", "ExitCode": 0, "Output": "{\"status\":\"OK\"}" } ]}Logには過去のチェック結果が直近何件か残る。ExitCodeが0以外になったらそこが失敗としてカウントされていく。
nginx側はcurlでHTTP、php-fpm側はcgi-fcgiでFastCGIと、プロトコルが違うだけで考え方は同じ。「コンテナの中で完結する形でヘルスチェック用のコマンドを1つ用意する」というのがHEALTHCHECKの基本形。