Express/React/Mongoアプリを立ち上げるためにdocker-compose
を使用しています。現在、Expressアプリの再試行ロジックを使用してすべてを立ち上げることができます。ただし、コンテナーが最初に起動するときのエラーの文字列を防ぐために、Dockerの healthcheck を使用したいと思います。ただし、docker-compose.yml
にhealthcheck
を追加すると、間隔/再試行の時間制限でハングし、次のように終了します。
ERROR: for collector Container "70e7aae49c64" is unhealthy.
ERROR: for server Container "70e7aae49c64" is unhealthy.
ERROR: Encountered errors while bringing up the project.
私のヘルスチェックは決して健全なステータスを返さないようで、なぜかは完全にはわかりません。 docker-compose.yml
全体:
version: "2.1"
services:
mongo:
image: mongo
volumes:
- ./data/mongodb/db:/data/db
ports:
- "${DB_PORT}:${DB_PORT}"
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongo mongo:27017/test --quiet 1
interval: 10s
timeout: 10s
retries: 5
collector:
build: ./collector/
environment:
- DB_Host=${DB_Host}
- DB_PORT=${DB_PORT}
- DB_NAME=${DB_NAME}
volumes:
- ./collector/:/app
depends_on:
mongo:
condition: service_healthy
server:
build: .
environment:
- SERVER_PORT=$SERVER_PORT
volumes:
- ./server/:/app
ports:
- "${SERVER_PORT}:${SERVER_PORT}"
depends_on:
mongo:
condition: service_healthy
test
についても、私は試しました:
["CMD", "nc", "-z", "localhost", "27017"]
そして:
["CMD", "bash", "/mongo-healthcheck"]
this guy のアドバイスに従って、healthcheck
を完全に破棄することも試みました。すべてが立ち上がりますが、接続が成功する前に、出力に恐ろしいエラーが表示されます。
collector_1 | MongoDB connection error: MongoNetworkError: failed to connect to server [mongo:27017] on first connect [MongoNetworkError: connect
ECONNREFUSED 172.21.0.2:27017]
collector_1 | MongoDB connection with retry
collector_1 | MongoDB connection error: MongoNetworkError: failed to connect to server [mongo:27017] on first connect
最終的な目標は、docker-compose up --build
を実行したときのクリーンな起動出力です。 この質問 でもいくつかの解決策を調べましたが、wait-for-it
でもあまりうまくいきませんでした。 Mongoが起動して実行されるのを待ってから、他のコンテナーを起動してクリーンな起動を実現する正しい方法は何ですか?
私はここで解決策を見つけました https://github.com/docker-library/healthcheck/tree/master/mongo
ヘルスチェックが公式画像に含まれていない理由を説明しています https://github.com/docker-library/cassandra/pull/76#issuecomment-246054271
docker-healthcheck
#!/bin/bash
set -eo pipefail
if mongo --quiet "localhost/test" --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)'; then
exit 0
fi
exit 1
リンクの例では、Host変数を使用しています
Host="$(hostname --ip-address || echo '127.0.0.1')"
if mongo --quiet "$Host/test" --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)'; then
# continues the same code
それは私にとってはうまくいきませんでしたので、Hostをlocalhostに置き換えました。
docker-compose内
mongo:
build:
context: "./mongodb"
dockerfile: Dockerfile
container_name: crm-mongo
restart: always
healthcheck:
test: ["CMD", "docker-healthcheck"]
interval: 10s
timeout: 2s
retries: 10
または、コンテナでヘルスチェックを実行できます。変更Dockerfileまたはそれ。
FROM mongo:4
ADD docker-healthcheck /usr/local/bin/
Dockerコンテナーでecho db.runCommand("ping").ok' | mongo localhost:27017/test --quiet 1
コマンドを実行すると、結果は次のようになります。
2019-04-19T02:39:19.770+0000 E - [main] file [1] doesn't exist
failed to load: 1
これを試して
healthcheck:
test: bash -c "if mongo --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)'; then exit 0; fi; exit 1;"