Docker Compose中单节点MongoDB副本集PyMongo连接失败问题
单节点MongoDB副本集跨容器PyMongo连接问题解决
问题情况
用Docker Compose搭建单节点MongoDB副本集后,从api容器通过PyMongo连接失败,但以下两种方式能正常连接:
- MongoDB Compass:
mongodb://admin:admin@localhost:27017 - api容器内使用mongosh:
docker exec -it api mongosh mongodb://admin:admin@mongodb
出错情况
进入api容器执行Python代码,初始化PyMongo客户端后调用server_info(),会抛出pymongo.errors.ServerSelectionTimeoutError,提示无法连接localhost:27017。
试过的操作
推测问题源于副本集初始化命令rs.initiate()中的节点配置{_id:0, host:'localhost:27017'}:
- 尝试将
host改为容器名mongodb或具体IP时,MongoDB容器直接崩溃,报错无法连接或节点配置不匹配; - 但在MongoDB容器内部可正常解析
mongodb主机名,且能用mongosh成功连接。
环境版本
- MongoDB 7.0.14
- Python 3.12.1
- PyMongo 4.8.0
- mongosh 2.3.1
解决办法
1. 修正副本集初始化的节点配置
副本集初始化必须使用其他容器可访问的主机名(即Docker Compose中MongoDB服务的名称mongodb),之前崩溃多是因为命令格式错误或MongoDB绑定IP限制。
正确的初始化命令需指定副本集名称,节点主机名要带端口,且需与MongoDB配置中的副本集名称一致:
rs.initiate({ _id: "rs0", // 该名称需与mongod.conf里的replication.replSetName保持一致 members: [ { _id: 0, host: "mongodb:27017" } ] })
2. 调整MongoDB配置文件
确保mongod.conf中包含以下正确配置:
replication: replSetName: "rs0" # 与初始化命令中的_id对应 net: bindIp: 0.0.0.0 # 允许所有IP访问,避免容器间连接被限制
3. 修正PyMongo连接字符串
PyMongo连接副本集必须指定副本集名称,且需使用容器名mongodb而非localhost:
from pymongo import MongoClient # 正确连接串,必须携带replicaSet参数 client = MongoClient("mongodb://admin:admin@mongodb:27017/?replicaSet=rs0") # 验证连接 print(client.server_info())
4. 确保初始化脚本在MongoDB就绪后执行
在Docker Compose中为MongoDB添加健康检查,保证其完全启动后再启动api容器,避免初始化脚本执行过早导致失败:
services: mongodb: image: mongo:7.0.14 volumes: - ./mongod.conf:/etc/mongod.conf - ./init-replica.js:/docker-entrypoint-initdb.d/init-replica.js command: ["mongod", "--config", "/etc/mongod.conf"] ports: - "27017:27017" environment: MONGO_INITDB_ROOT_USERNAME: admin MONGO_INITDB_ROOT_PASSWORD: admin healthcheck: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] interval: 5s timeout: 5s retries: 5 api: build: ./api depends_on: mongodb: condition: service_healthy
关键说明
- 副本集节点的
host不能用localhost,该地址仅在MongoDB容器内部有效,其他容器无法解析; - PyMongo连接副本集必须添加
replicaSet参数,否则会以单实例模式连接,直接触发节点选择超时; - 健康检查能避免
api容器在MongoDB未完全就绪时启动,减少初始化失败概率。
内容的提问来源于stack exchange,提问作者Spotika4
相关产品推荐
相关产品推荐

