Docker Compose中配置Mongo Express等待MongoDB集群就绪方法
解决方案
depends_on默认只会等待容器进程启动,不会等容器内的服务真正就绪,MongoDB副本集还要经历主节点初始化、从节点/仲裁节点加入、选主几个步骤,从启动到可正常接受连接有十几秒到几十秒的延迟,直接启动Mongo Express必然会出现连接失败的问题。
不用额外引入第三方等待工具,直接用Docker Compose原生的健康检查能力+Mongo Express自带的连接重试就能解决,修改后的可用配置如下:
version: '3.9' services: mongodb-primary: image: 'bitnami/mongodb:6.0' environment: - MONGODB_ADVERTISED_HOSTNAME=mongodb-primary - MONGODB_REPLICA_SET_MODE=primary - MONGODB_ROOT_PASSWORD=password - MONGODB_REPLICA_SET_KEY=replicasetkey volumes: - 'mongodb_master_data:/bitnami' healthcheck: test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"] interval: 5s timeout: 5s retries: 10 start_period: 30s mongodb-secondary: image: 'bitnami/mongodb:6.0' depends_on: - mongodb-primary environment: - MONGODB_ADVERTISED_HOSTNAME=mongodb-secondary - MONGODB_REPLICA_SET_MODE=secondary - MONGODB_INITIAL_PRIMARY_HOST=mongodb-primary - MONGODB_INITIAL_PRIMARY_PORT_NUMBER=27017 - MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD=password - MONGODB_REPLICA_SET_KEY=replicasetkey healthcheck: test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"] interval: 5s timeout: 5s retries: 10 start_period: 40s mongodb-arbiter: image: 'bitnami/mongodb:6.0' depends_on: - mongodb-primary environment: - MONGODB_ADVERTISED_HOSTNAME=mongodb-arbiter - MONGODB_REPLICA_SET_MODE=arbiter - MONGODB_INITIAL_PRIMARY_HOST=mongodb-primary - MONGODB_INITIAL_PRIMARY_PORT_NUMBER=27017 - MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD=password - MONGODB_REPLICA_SET_KEY=replicasetkey healthcheck: test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"] interval: 5s timeout: 5s retries: 10 start_period: 30s dbadmin: image: mongo-express:latest restart: always ports: - 8081:8081 depends_on: mongodb-primary: condition: service_healthy mongodb-secondary: condition: service_healthy mongodb-arbiter: condition: service_healthy environment: ME_CONFIG_MONGODB_URL: mongodb://root:password@mongodb-primary:27017,mongodb-secondary:27017,mongodb-arbiter:27017?replicaSet=replicaset ME_CONFIG_BASICAUTH_USERNAME: admin ME_CONFIG_BASICAUTH_PASSWORD: mexpress ME_CONFIG_MONGODB_CONNECT_RETRIES: 20 ME_CONFIG_MONGODB_CONNECT_TIMEOUT: 5000 volumes: mongodb_master_data: driver: local
配置说明
- 把原配置中用
latest标签的MongoDB镜像固定到6.0版本,避免镜像自动更新导致环境变量、初始化逻辑变动,出现无厘头的启动失败 - 给三个MongoDB节点都加了健康检查,直接调用
mongosh执行ping命令校验服务是否真正可用,比单纯检查27017端口是否监听靠谱。从节点需要同步主节点的副本集配置,所以把启动宽限期设得比主节点、仲裁节点长10秒,避免初始化阶段被误判为不健康反复重启 - 把dbadmin服务的
depends_on改成service_healthy条件,只有三个Mongo节点全部通过健康检查,才会启动Mongo Express - 给Mongo Express加了连接重试参数做兜底:就算节点都通过健康检查,副本集刚选主完成时可能有秒级的连接闪断,自动重试20次、每次间隔5秒,完全能覆盖这个窗口
如果之前启动失败残留了错误的副本集数据,先执行docker compose down -v删掉旧卷再重新启动即可,本地开发环境这么操作没有副作用。
内容的提问来源于stack exchange,提问作者unspeakable29
相关产品推荐
相关产品推荐

