Docker环境下Python服务无法连接MongoDB服务器的求助
Docker容器内MongoDB连接超时(Connection refused)问题解决
问题现象
在Docker Compose部署的同一网络中,block_scraper服务尝试连接storage(MongoDB)服务时,出现以下超时错误:
pymongo.errors.ServerSelectionTimeoutError: storage:27017: [Errno 111] Connection refused, Timeout: 30s, Topology Description: <TopologyDescription id: 64f24e6e941b3aa3dea67cc9, topology_type: Unknown, servers: [<ServerDescription ('storage', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('storage:27017: [Errno 111] Connection refused')>]>
本地直接运行两个服务时正常,但Docker容器内无法通信。
解决方案
1. 处理MongoDB启动延迟问题
depends_on仅保证容器启动顺序,不代表MongoDB服务已完全就绪。添加连接重试逻辑确保服务可用后再建立连接:
修改db_connector.py为:
import os import pymongo from pymongo.errors import ServerSelectionTimeoutError import time mongo_host = os.environ.get("STORAGE_CONNECTION_STR") client = None def get_client(): global client if client is None: max_retries = 5 retry_delay = 5 for attempt in range(max_retries): try: client = pymongo.MongoClient(mongo_host, serverSelectionTimeoutMS=5000) # 发送ping命令验证连接 client.admin.command('ping') return client except ServerSelectionTimeoutError: if attempt < max_retries - 1: time.sleep(retry_delay) else: raise return client def get_collection(mongo_db_name="blocks101", mongo_collection_name="block"): client = get_client() database = client[mongo_db_name] return database[mongo_collection_name] def close(): if client: client.close()
2. 确保MongoDB绑定所有IP
部分MongoDB镜像可能默认仅绑定127.0.0.1,导致容器间无法访问。在docker-compose.yml中添加command参数强制绑定所有IP:
services: storage: # ... 其他配置不变 command: mongod --bind_ip_all
3. 验证容器网络连通性
进入block_scraper容器,测试与storage的网络连通性:
# 进入block_scraper容器 docker exec -it <block_scraper容器ID或名称> /bin/bash # 测试ping连通性 ping storage # 测试27017端口是否开放 nc -zv storage 27017
如果ping通但nc失败,说明MongoDB服务未正常启动;如果ping不通,检查Docker网络配置是否正确(确认两个服务都在scraper_network网络中)。
4. 检查环境变量是否正确传递
在block_scraper容器内验证环境变量:
echo $STORAGE_CONNECTION_STR
确认输出为mongodb://storage:27017,若为空则检查docker-compose.yml中环境变量配置是否正确。
5. 查看MongoDB启动日志
检查MongoDB容器日志,确认服务是否正常初始化:
docker logs mongodb
日志中出现waiting for connections on port 27017说明服务已就绪。
内容的提问来源于stack exchange,提问作者MrChadMWood
相关产品推荐
相关产品推荐

