?? 問題背景
在 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 網絡結構,請參考官方文檔: