为什么我的mongo容器的docker-compose healthcheck总是失败?

问题描述 投票:1回答:3

我正在使用docker-compose来支持Express / React / Mongo应用程序。我现在可以使用快速应用程序中的重试逻辑来站起来。但是,我更喜欢使用Docker的healthcheck来防止容器最初旋转时出现错误。但是,当我在healthcheck中添加docker-compose.yml时,它会挂起间隔/重试时间限制并退出:

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

根据healthcheck的建议,我也尝试完全抛弃this guy。一切都站起来,但在连接成功之前,我在输出中遇到了可怕的错误:

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时获得干净的启动输出。我也研究了this question的一些解决方案,但我也没有和wait-for-it一点运气。在启动其他容器并实现干净启动之前,等待Mongo启动并运行的正确方法是什么?

mongodb docker docker-compose
3个回答
4
投票

首先我建议将docker-compose.yaml文件版本更新到至少3.4(version: "3.5"),然后请将start_period选项添加到您的mongo healthcheck

注意:start_period仅支持v3.4及更高版本的撰写文件格式。

start period为需要时间引导的容器提供初始化时间。在此期间探测失败将不计入最大重试次数。但是,如果在启动期间运行状况检查成功,则会将容器视为已启动,并且所有连续失败将计入最大重试次数。

所以它看起来像这样:

healthcheck:
  test: echo 'db.runCommand("ping").ok' | mongo mongo:27017/test --quiet 1
  interval: 10s
  timeout: 10s
  retries: 5
  start_period: 40s

1
投票

我在这里找到了一个解决方案https://github.com/docker-library/healthcheck/tree/master/mongo

请注意,它解释了为什么健康检查不包括在官方图像https://github.com/docker-library/cassandra/pull/76#issuecomment-246054271

泊坞窗,健康检查

#!/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="$(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

它对我不起作用,所以我用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/

0
投票

当我在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

试试这个echo 'db.runCommand("ping").ok' | mongo mongo:27017/test --quiet | echo $?

© www.soinside.com 2019 - 2024. All rights reserved.