容器化Python-Flask应用连接MongoDB遇Error 111连接拒绝问题求助
Flask+MongoDB容器化连接拒绝(Error 111)问题解决
核心问题原因
本地运行正常但容器化后连接失败,本质是容器间网络访问配置错误,或MongoDB未完全就绪时Flask提前启动。
解决方案1:修正MongoDB连接字符串
本地开发时你可能用localhost:27017连接MongoDB,但容器环境中,需要用docker-compose定义的服务名作为主机地址,且容器内部MongoDB默认端口是27017(宿主机映射的27018仅用于外部访问)。
修改Flask代码中的连接代码:
# 错误写法(本地可用,容器不可用) client = pymongo.MongoClient("mongodb://localhost:27017/") # 正确写法(容器环境可用) client = pymongo.MongoClient("mongodb://mongodb:27017/")
这里的mongodb是docker-compose.yml中定义的MongoDB服务名,容器间通过服务名自动解析IP。
解决方案2:确保MongoDB就绪后再启动Flask
depends_on仅保证容器启动顺序,不保证MongoDB服务完全初始化完成。如果Flask启动时MongoDB还没准备好,就会触发连接拒绝错误。
方法A:添加MongoDB健康检查(推荐,docker-compose 3+支持)
修改docker-compose.yml,给MongoDB服务添加健康检查,并让Flask等待MongoDB健康状态:
version: '3.8' # 升级到支持healthcheck的版本 networks: app-tier: driver: bridge services: myapp: image: 'chatapp' networks: - app-tier ports: - 8000:8000 depends_on: mongodb: condition: service_healthy # 等待MongoDB健康检查通过 mongodb: image: 'mongo' networks: - app-tier environment: - ALLOW_EMPTY_PASSWORD=yes ports: - 27018:27017 healthcheck: test: ["CMD", "mongo", "--eval", "db.adminCommand('ping')"] interval: 5s # 每5秒检查一次 timeout: 5s # 超时时间5秒 retries: 5 # 重试5次后标记为不健康
方法B:在Flask中添加连接重试逻辑
如果不想升级docker-compose版本,可以在Flask的MongoDB连接代码中加入重试机制:
from pymongo import MongoClient from pymongo.errors import ConnectionFailure import time def get_mongo_client(): max_retries = 5 retry_delay = 2 for _ in range(max_retries): try: client = MongoClient("mongodb://mongodb:27017/") # 验证连接 client.admin.command('ping') return client except ConnectionFailure: time.sleep(retry_delay) raise Exception("Failed to connect to MongoDB after multiple retries") # 使用该函数获取客户端 client = get_mongo_client()
解决方案3:移除过时的links配置
links是Docker旧版的容器关联方式,在自定义网络(如app-tier)下,容器间默认可以通过服务名互相访问,无需额外配置links。直接删除docker-compose.yml中myapp服务下的links: - mongodb即可,不影响网络访问。
内容的提问来源于stack exchange,提问作者Dev Saini
相关产品推荐
相关产品推荐

