🚏
dockerのnginxがredisにアクセス出来ず起動できない件
タイトルについて
共感の得やすいタイトルにしたけれど、その実態はdockerのredisの立ち上がりが遅い件だ。
単純なdepends_on
docker-composeを使う時、多くは起動順序の設定のためにdepends_on
を書く。しかしそれだけだとnginx
とredis
を組み合わせた時に問題が発生する。redisが起動して準備完了する前にnginxの起動が始まってしまうので、redisを使ったupstreamを定義しようとするとエラーになってしまうのだ。
対応できずに各コンテナにipv4アドレス振って対応した人やupstreamの使用を諦めた人もいるのではないだろうか?
問題のあるdepends_on
depends_on:
- redis
- memcached
- mysql
問題のあるdocker-compose.yml
docker-compose.yml
version: "3.9"
services:
redis:
image: "redis:alpine"
mysql:
image: "mysql:8.0"
environment:
MYSQL_ROOT_PASSWORD: example
adminer:
image: adminer
restart: always
ports:
- 8080:8080
nginx:
image: "openresty/openresty:alpine"
ports:
- 80:80
depends_on:
- redis
- memcached
- mysql
拘ったdepends_on
このdepends_on
を下記のように書き換える事で、nginxからredisへ投げるヘルスチェックが通ってからnginxを立ち上げてくれるようになる。
拘ったdepends_on
nginx:
depends_on:
redis:
condition: service_healthy
そしてredis側にはヘルスチェックの内容を追加する
ヘルスチェック
redis:
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping", "|", "grep", "PONG"]
timeout: 5s
retries: 5
start_period: 5s
改善されたdocker-compose.yaml
docker-compose
version: "3.9"
services:
redis:
image: "redis:alpine"
expose:
- 6379
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping", "|", "grep", "PONG"]
timeout: 5s
retries: 5
start_period: 5s
memcached:
image: "memcached:alpine"
mysql:
image: "mysql:8.0"
environment:
MYSQL_ROOT_PASSWORD: example
adminer:
image: adminer
restart: always
ports:
- 8080:8080
nginx:
image: "openresty/openresty:alpine"
ports:
- 80:80
depends_on:
redis:
condition: service_healthy
memcached:
condition: service_started
mysql:
condition: service_started
気をつけるところ
redisのhealthcheckでgrep PONG
が無いと意図したチェック動作とならない。
Discussion