🧩 问题背景
在 FastGPT 的本地开发过程中,许多开发者会遇到这样一个疑问:
✅ 为什么在
docker-compose.yml
中配置 MongoDB 地址为mongo
就可以正常连接,而在.env.local
中却必须写localhost
才行?
如果配置错误,可能会出现:
MongooseError: Connection operation buffering timed out after 10000ms
- 服务运行时
pnpm dev
一直卡住,数据库连接不上
🧠 原因分析:Docker 网络与主机网络的差异
1. 🐳 Docker 容器内部网络是隔离的
当你使用 docker-compose up
启动服务时,Docker 会创建一个自定义网络(比如叫 fastgpt
)。此网络允许容器间通过 服务名 相互访问,例如:
服务名 | 作用 |
---|---|
mongo |
表示 MongoDB 容器 |
pg |
表示 PostgreSQL 容器 |
redis |
表示 Redis 容器 |
🔗 容器之间通过服务名通信 是 Docker 的 DNS 解析功能实现的。
示例:
在 docker-compose.yml
中:
MONGODB_URI: mongodb://mongo:27017/fastgpt?authSource=admin
这是 容器内访问容器 的方式,只在容器中有效!
2. 🖥️ 主机(开发环境)访问 Docker 容器:必须使用 localhost
当你在本地使用 pnpm dev
启动 FastGPT 应用时,它运行在 主机网络 上,这时候不能解析 mongo
这样的容器服务名。
这时候你只能通过 localhost:<映射端口>
的方式访问容器内服务。
示例端口映射(来自 docker-compose.yml
):
ports:
- 27017:27017 # Mongo
- 5432:5432 # Postgres
- 6379:6379 # Redis
因此,在 .env.local
中你必须写成:
MONGODB_URI=mongodb://localhost:27017/fastgpt?authSource=admin&directConnection=true
🔁 主机访问容器:localhost:容器暴露的端口
✅ 总结:连接方式对比
场景 | 主机名 | 说明 |
---|---|---|
容器内访问容器 |
mongo , pg , redis
|
依赖 Docker 内置 DNS |
主机访问容器 |
localhost , 127.0.0.1
|
依赖端口映射(如 27017 → mongo 容器) |
🔐 小贴士
-
directConnection=true
是连接 MongoDB 副本集的关键参数(用于避免 DNS SRV 解析) -
.env.local
是给主机开发模式用的,不能复制.env
或docker-compose
的写法 - 使用
docker ps
确认容器已运行,并确保端口映射正确 - 可用
curl
,telnet
, 或数据库客户端(如 Compass / Navicat)验证连通性
🏁 最佳实践
✔ 推荐的 .env.local
示例(本地开发)
MONGODB_URI=mongodb://localhost:27017/fastgpt?authSource=admin&directConnection=true
PG_URL=postgresql://fastgpt:fastgpt@localhost:5432/fastgpt
REDIS_URL=redis://localhost:6379
✔ 推荐的 docker-compose.yml
示例(容器内通信)
environment:
MONGODB_URI: mongodb://mongo:27017/fastgpt?authSource=admin
PG_URL: postgresql://fastgpt:fastgpt@pg:5432/fastgpt
REDIS_URL: redis://redis:6379
📌 FAQ 快速排查
错误提示 | 原因 |
---|---|
MongooseError: Connection operation buffering timed out |
Mongo 地址写错了(容器名在主机中不可解析) |
Connection refused |
端口未暴露或防火墙未开放 |
页面打不开 | 服务未启动,或 .env.local 未正确配置 |
如需进一步理解 Docker 网络结构,请参考官方文档: