Docker Compose中Mongo容器偶发连接失败问题求助
解决Docker Compose容器重启后无限循环连接Mongo失败的问题
这是典型的容器启动依赖与网络就绪性问题,虽然你用了links,但这个特性已经被Docker弃用,而且它根本没法保证Mongo服务真正就绪后再启动你的应用容器。结合你的场景,给你几个针对性的解决思路:
1. 用健康检查+依赖条件替代旧的links
depends_on默认只会保证Mongo容器先启动,但不会等它的服务真正能接受连接。给Mongo加上健康检查,让应用容器等Mongo完全就绪后再启动,这是最根本的解决方案。修改你的docker-compose.yml如下:
version: "3.8" # 升级到支持健康检查条件的版本 services: sourcejs: image: neogucky/myapplication command: /bin/bash /home/myapplication/startScript.sh ports: - "80:8080" restart: always depends_on: mongo: condition: service_healthy # 等待Mongo健康检查通过才启动 mongo: image: mongo ports: - "27017:27017" restart: always healthcheck: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] interval: 10s # 每10秒检查一次 timeout: 5s # 超时时间5秒 retries: 5 # 最多重试5次,失败则标记为不健康
这样你的应用容器会一直等到Mongo能正常响应ping命令后才开始执行启动脚本,从根源避免了连接失败的问题。
2. 在启动脚本中添加Mongo连接重试逻辑
考虑到你的启动脚本需要2分钟才会走到连接Mongo的步骤,就算容器启动顺序没问题,也可能遇到Mongo服务还没完全初始化的情况。在启动脚本里加入一段等待Mongo就绪的逻辑,比如:
# 在启动应用之前,先等待Mongo可连接 until mongosh --host mongo --eval "db.adminCommand('ping')" >/dev/null 2>&1; do echo "Waiting for MongoDB to become available..." sleep 10 done # 继续执行后面的Git更新和应用启动逻辑 # ...
这段代码会循环检查Mongo的连通性,直到能正常连接才继续执行后续步骤,就算容器提前启动也不会直接报错退出。
3. 使用自定义Docker网络提升DNS稳定性
重启服务器后,Docker默认的bridge网络可能存在DNS解析延迟或者异常,导致你的应用容器找不到mongo主机。可以自定义一个网络来避免这个问题:
version: "3.8" services: sourcejs: # ... 其他配置 networks: - app-internal mongo: # ... 其他配置 networks: - app-internal networks: app-internal: driver: bridge
自定义网络的DNS解析机制比默认网络更稳定,能减少重启后主机名解析失败的概率。
4. 临时调整重启策略(用于排查)
如果上面的方法还没生效,可以先把应用容器的重启策略从always改成on-failure,避免无限重启影响排查:
restart: on-failure:5 # 最多重启5次,失败后停止
等问题解决后再改回always即可。
内容的提问来源于stack exchange,提问作者Tim Rasim
相关产品推荐
相关产品推荐

