🐳 Dockerのヘルスチェックとは?
コンテナの起動タイミングを制御する実践ガイド
問題の発生
Dockerで少し複雑な環境を構築していると、少し困った事が起きました。
サーバーを建てて、サーバー内で以下のコマンドを実行させているのですが:
chown www:www /run/php-fpm/www.sock
chmod 777 /run/php-fpm/www.sock
問題: サーバーを建てている途中に、このシェルが走ってしまうようで、毎回エラーになる。
感覚的には3秒ほど待ってから実行すればいけると思う。
解決策:ヘルスチェック
Dockerで、ビルドが終わってから、次の命令を実行させる方法はないか探していたところ、「healthcheck」という方法があるらしい。
ただ、この方法結構マニアックなやり方らしく、Dockerの本3冊位読んで勉強したけど、こんなの出てきたかなと…。
ネットで探しても「意味ない」「使い方わからん」のような記事が出てくる。
わからんので検証してみる。
ヘルスチェックの基本
書き方
healthcheck:
test: ["CMD", "sh", "-c", "db2 connect to testdb"]
interval: 1s
timeout: 1s
retries: 10
start_period: 1s
📝 コマンドの意味
- test:ヘルスチェックをするコマンド内容を書く
- interval:testのコマンドの実行間隔、5sと書いたら5秒に一回コマンドを実行する
- timeout:タイムアウトの時間、この時間内にコマンドが成功しないと、またintervalに戻る
- retries:リトライする回数、3と書いたら、3回失敗したらステータスが「ヘルシーじゃない」となる
- start_period:最初のコマンドを実行するまでの時間
実践:WordPressでの検証
ヘルスチェックなしの場合
services:
wordpress:
image: wordpress:latest
ports:
- "80:80"
volumes:
- ./www:/var/www/html
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: test
WORDPRESS_DB_PASSWORD: test
WORDPRESS_DB_NAME: test
depends_on:
- mysql
mysql:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: test
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_DATABASE: test
問題点:
このDocker、もちろん成功するのですが、1点問題があります。
ビルドが終わってすぐにアクセスすると http://localhost/ でエラーになります。
3秒くらい待ってからアクセスすると成功する。
つまり、MySQLの起動が終わってないのにビルドが終わってしまう。
ヘルスチェックありの場合
MySQLの起動が終わってから、ビルド完了させたい。では、WordPressのYMLファイルにヘルスチェックを入れてみます。
services:
wordpress:
image: wordpress:latest
ports:
- "80:80"
volumes:
- ./www:/var/www/html
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: test
WORDPRESS_DB_PASSWORD: test
WORDPRESS_DB_NAME: test
depends_on:
mysql:
condition: service_healthy
mysql:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: test
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_DATABASE: test
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "mysql", "-u", "test", "-ptest"]
interval: 2s
timeout: 10s
retries: 3
start_period: 1s
これでビルドしてみます:
docker-compose up -d
すると5秒くらいですがWaitingになります。
少し待つとMySQLがHealthyとなる。
すぐにlocalhostにアクセスしてみると…
✅ エラーにならず接続出来た!!
Dockerfileでヘルスチェック
YMLファイルでのヘルスチェックはわかりました。これは全然使える。
でも、環境構築が大きくなると、Dockerfileでヘルスチェックしたい時もある。
抱えている問題
大きめの環境構築で、Dockerfileでシェルを読ませて、その後にさらに権限変更をやらせようとしています。
ENTRYPOINT ["/docker-entrypoint.sh"]
RUN chown www:www /run/php-fpm/www.sock
RUN chmod 777 /run/php-fpm/www.sock
ただ、これは上手くいかず、アクセスするとエラーになってしまう。
手動でコマンドを実行すればアクセス出来るようになるのですが、これをヘルスチェックでやらせてみたい。
手動でコマンドを実行すればアクセス出来るようになるのですが、これをヘルスチェックでやらせてみたい。
解決方法
Dockerfileの最後に以下を追加:
# 構築に時間がかかるので構築終わってからの処理をヘルスチェックで対応
HEALTHCHECK --interval=5s --timeout=3s --retries=5 \
CMD test -S /run/php-fpm/www.sock && chown www:www /run/php-fpm/www.sock && chmod 777 /run/php-fpm/www.sock || exit 1
✅ これで、15秒ほど待ってからアクセスすると成功します!!
📝 仕組みの説明
HEALTHCHECK --interval=5s --timeout=3s --retries=5で処理の時間を決定- その後の
&& ~~~~~~~~ || exit 1ここの「~~~~」に成功した場合の処理を書く - 成功するまで繰り返してくれるので、かなり使える
まとめ
- ヘルスチェックは、コンテナの起動タイミングを制御するための強力なツール
- docker-compose.ymlとDockerfileの両方で使用可能
- マニアックだが、複雑な環境構築では必須のテクニック
- 成功するまで繰り返し実行してくれるので、タイミング問題を解決できる

コメント