![](/img/trans.png)
[英]Why does my mongo container in docker-compose keep exiting?
[英]Why does the docker-compose healthcheck of my mongo container always fail?
我正在使用docker-compose
建立一个 Express/React/Mongo 应用程序。 我目前可以在 express 应用程序中使用重试逻辑来解决所有问题。 但是,我更愿意使用Docker的健康检查来防止容器最初启动时出现错误串。 但是,当我在我的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
完全放弃健康检查,听从这个人的建议。 一切正常,但在成功连接之前,我在 output 中遇到了可怕的错误:
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
时干净启动 output。 我也研究了这个问题中的一些解决方案,但我也没有太多运气wait-for-it
。 在启动其他容器并实现干净启动之前等待 Mongo 启动并运行的正确方法是什么?
首先,我建议将 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
interval: 10s
timeout: 10s
retries: 5
start_period: 40s
我们可以使用 MongoDB 的serverStatus命令来进行健康检查,就像 MongoDB 文档这样说的:
监控应用程序可以定期运行此命令来收集有关实例的统计信息。
由于此命令serverStatus
需要身份验证,因此您需要设置类似于以下配置的健康检查:
version: '3.4'
services:
mongo:
image: mongo
restart: always
healthcheck:
test: echo 'db.runCommand({serverStatus:1}).ok' | mongo admin -u $MONGO_INITDB_ROOT_USERNAME -p $MONGO_INITDB_ROOT_PASSWORD --quiet | grep 1
interval: 10s
timeout: 10s
retries: 3
start_period: 20s
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
就是这样。 如果您的 MongoDB 实例运行状况良好,您将看到与我类似的内容:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
01ed0e02aa70 mongo "docker-entrypoint.s…" 11 minutes ago Up 11 minutes (healthy) 27017/tcp demo_mongo_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/
请注意,如果您使用 mongodb 的较新版本,您可能应该使用 mongosh:
healthcheck:
test: ["CMD","mongosh", "--eval", "db.adminCommand('ping')"]
interval: 5s
timeout: 5s
retries: 3
start_period: 5s
当我执行echo db.runCommand("ping").ok' | mongo localhost:27017/test --quiet 1
echo db.runCommand("ping").ok' | mongo localhost:27017/test --quiet 1
命令在docker容器中,结果为:
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;"
这个对我有用:
healthcheck:
test: ["CMD","mongo", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 10s
retries: 5
从 MongoDB 6.0 中删除了 mongo shell。 替代品是mongosh。
尝试这个。 echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
mongo:图像:mongo 健康检查:测试:echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.