本文来自一次真实 Windows + Git Bash + Docker 部署过程的踩坑复盘。
若你正在面对:
ERR_TOO_MANY_REDIRECTS、404、502 Bad Gateway、Conflict. The container name "/docker-web-1",可以直接对号入座。
一、事故现场长什么样
症状组合拳:
- 访问
http://localhost或/dify/→重定向过多 - 有时变成404
- 退回官方端口
8085后又是502 docker compose报找不到配置文件- 重建 web 报容器名冲突
代理日志里出现过这种死亡循环:
GET /dify → 301 → /dify/ GET /dify/ → 308 → /dify GET /dify → 301 → /dify/ ...Nginx 补斜杠,Next.js 去斜杠,两边对打,浏览器直接放弃。
二、错误路线是怎么走偏的
最初官方栈其实已映射:
0.0.0.0:8085 → docker-nginx-1:80但排障过程中引入了额外目标:
- 再起一个
dify-proxy占 80 端口 - 给前端加
NEXT_PUBLIC_BASE_PATH=/dify - 用
docker run手工替换docker-web-1 - 把 API 地址写成
172.18.0.x硬编码 IP - 启动时使用不存在的
--profile core
于是问题从「先把官方入口跑通」变成「子路径 + 自定义代理 + IP 漂移」三重地狱。
三、每个报错的真实含义
1)no configuration file provided: not found
你在错误目录执行了 compose:
# 错 cd /d/Dify docker compose ps 对 cd /d/Dify/dify/docker docker compose ps2)重定向过多(301 ↔ 308)
根因通常是两套规则冲突:
| 组件 | 行为 |
|---|---|
| Nginx | /dify301 到/dify/ |
| Next.js(BASE_PATH=/dify) | /dify/308 到/dify |
修法:本地部署不要上/dify。
删掉NEXT_PUBLIC_BASE_PATH,删掉自定义dify-proxy,回http://localhost:8085根路径。
3)404
常见原因:
- 自定义 nginx 没
proxy_pass,在容器默认 html 目录找/dify/index.html BASE_PATH配了,但请求没打到对应路径- Git Bash 把
/dify翻译成C:/Program Files/Git/dify,basePath 彻底错乱
真实案例环境变量:
NEXT_PUBLIC_BASE_PATH=C:/Program Files/Git/dify这是 Git Bash 路径转换造成的,不是 Dify 官方设定。
4)502 Bad Gateway
Nginx 活着,上游挂了或 IP 过期:
connect() failed (111: Connection refused) upstream: "http://172.18.0.4:3000/"复盘时172.18.0.4已经变成plugin_daemon,而真正的 web 在172.18.0.8。
原因:web 被docker run重建后 IP 变了,nginx 仍缓存旧 upstream。
修法:
docker compose up -d --force-recreate nginx web5)500 Internal Server Error +db_postgres解析失败
could not translate host name "db_postgres" to address说明PostgreSQL 容器没启动。
常见诱因:使用了无效的--profile core,只起了应用层,没起postgresql/weaviateprofile。
正确启动:
cd /d/Dify/dify/docker docker compose --profile postgresql --profile weaviate --profile collaboration up -d6)容器名 Conflict
Conflict. The container name "/docker-web-1" is already in use说明有人用docker run --name docker-web-1创建过同名容器。
compose 无法静默覆盖。
处理:
docker rm -f docker-web-1 dify-proxy cd /d/Dify/dify/docker docker compose up -d --force-recreate web nginx四、推荐的"止血顺序"(按优先级)
把下面当成排障 SOP:
Step 1:回到官方入口,先放弃自定义代理
cd /d/Dify/dify/docker docker rm -f dify-proxyStep 2:清掉被污染的 web,交还给 compose
docker rm -f docker-web-1Step 3:确认.env是浏览器可达地址
CONSOLE_API_URL=http://localhost:8085 CONSOLE_WEB_URL=http://localhost:8085 APP_API_URL=http://localhost:8085 APP_WEB_URL=http://localhost:8085 SERVER_CONSOLE_API_URL=http://api:5001 EXPOSE_NGINX_PORT=8085并检查docker-compose.yaml的web.environment没有硬编码172.18.x.x。
Step 4:用正确 profile 拉起数据库和向量库
docker compose --profile postgresql --profile weaviate --profile collaboration up -dStep 5:重建关键链路
docker compose up -d --force-recreate api web nginxStep 6:验收
docker compose ps curl -I http://localhost:8085/成功信号:
HTTP/1.1 307 Temporary Redirect location: /install或登录页 200。然后用无痕窗口打开,避免旧 301/308 被浏览器缓存。
五、如果必须挂在子路径/dify(一般不建议)
只有在"同一域名多系统共存"时才考虑。要同时满足:
- Nginx不要再对
/dify强制补/ proxy_pass原样转发,不要二次改写路径制造双斜杠规则- 前后端 base path 一致
- 用 curl 验证不能出现 301↔308:
curl -sI http://localhost/dify | head -5 curl -sI http://localhost/dify/ | head -5本地知识库学习场景:直接用根路径更稳。
六、Git Bash 防坑速查
# 进容器 winpty docker exec -it docker-web-1 //bin/sh 读文件 docker exec docker-web-1 //bin/cat //etc/hosts 避免 -e 路径被改写(若必须传 Unix 路径) MSYS2_ARG_CONV_EXCL='*' docker ...永远优先:
docker compose exec web sh而不是手动docker run造同名容器。
七、一句话结论
| 表面错误 | 真实病因 | 正确动作 |
|---|---|---|
| 重定向过多 | /dify斜杠规则互殴 | 去掉 BASE_PATH 与自定义 301 |
| 404 | 代理没打到上游 / basePath 被 Git 改写 | 回官方根路径 |
| 502 | nginx upstream IP 过期或 web 挂 | recreate nginx/web |
| 500 | 没启 postgres | 加 postgresql profile |
| Conflict | docker run 污染 | docker rm -f后交给 compose |
| compose not found | 目录不对 | 进dify/docker |
最终稳妥访问方式:
http://localhost:8085先把官方栈跑绿,再谈换端口、换局域网 IP、换域名。
换地址请看系列文:《Dify 本地部署改局域网访问:避开 4 大坑,一次配对》。