web-dev-qa-db-ja.com

mongoコンテナのdocker-compose healthcheckが常に失敗するのはなぜですか?

Express/React/Mongoアプリを立ち上げるためにdocker-composeを使用しています。現在、Expressアプリの再試行ロジックを使用してすべてを立ち上げることができます。ただし、コンテナーが最初に起動するときのエラーの文字列を防ぐために、Dockerの healthcheck を使用したいと思います。ただし、docker-compose.ymlhealthcheckを追加すると、間隔/再試行の時間制限でハングし、次のように終了します。

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が起動して実行されるのを待ってから、他のコンテナーを起動してクリーンな起動を実現する正しい方法は何ですか?

6
Matthew Johnson

私はここで解決策を見つけました 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

それは私にとってはうまくいきませんでしたので、Hostlocalhostに置き換えました。

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/
1
Yan Khonski

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;"

0
Andrei