如何通过pymongo从本地主机连接Docker容器内的MongoDB?
我知道这本该是个简单的问题,之前实现过但忘了操作方法:我的MongoDB通过Docker Compose以服务形式运行在容器中,同一Compose里还有一个基于FastAPI构建的API。我能通过下面的代码从API容器连接数据库:
from pymongo.mongo_client import MongoClient from pymongo.server_api import ServerApi client = MongoClient('mongodb://USERNAME:PASSWORD@mongo:27017/', server_api=ServerApi('1'), serverSelectionTimeoutMS=5000) client.server_info()
但从本地机器的Jupyter Notebook执行相同代码时,出现如下错误:
ServerSelectionTimeoutError: mongo:27017: [Errno 8] nodename nor servname provided, or not known, Timeout: 5.0s, Topology Description: <TopologyDescription id: 63b6adb8b6aabb1624b50879, topology_type: Unknown, servers: [<ServerDescription ('mongo', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('mongo:27017: [Errno 8] nodename nor servname provided, or not known')>]>
我的docker-compose配置如下,之前能从本地连接MongoDB时它运行正常(所以我认为配置没问题):
version: '3.8' services: api: container_name: XXXXX restart: unless-stopped build: context: . dockerfile: ./API/API.Dockerfile volumes: - "./:/API" - type: bind source: XXXXX target: /Data ports: - "5001:5001" depends_on: - mongo env_file: - ./secrets/secrets.env mongo: container_name: mongo ports: - 27017:27017 image: mongo restart: always env_file: - ./secrets/secrets.env mongo-express: container_name: Mongo_Express image: mongo-express restart: always ports: - 8081:8081 env_file: - ./secrets/secrets.env
问题核心是主机名解析差异:
- Docker Compose内部网络中,
mongo是MongoDB服务的专属主机名,API容器处于这个网络内,能直接通过该名称定位数据库容器。 - 本地机器不在Docker内部网络,无法识别
mongo这个主机名,必须替换为本地可访问的地址。
修改连接字符串即可解决:
# 用localhost或本地IP替换mongo client = MongoClient('mongodb://USERNAME:PASSWORD@localhost:27017/', server_api=ServerApi('1'), serverSelectionTimeoutMS=5000)
如果localhost无法生效,也可以换成你的本地机器IP(比如192.168.3.10)。
额外确认两点:
- 你的docker-compose配置中,
mongo服务已经正确映射了27017:27017端口(当前配置已满足)。 - 本地防火墙没有拦截27017端口的入站连接。
内容的提问来源于stack exchange,提问作者Fabio Magarelli

