Dify 本地部署排坑实录:404 / 重定向过多 / 502 到底怎么修

Dify 本地部署排坑实录:404 / 重定向过多 / 502 到底怎么修

本文来自一次真实 Windows + Git Bash + Docker 部署过程的踩坑复盘。

若你正在面对:ERR_TOO_MANY_REDIRECTS404502 Bad GatewayConflict. The container name "/docker-web-1",可以直接对号入座。


一、事故现场长什么样

症状组合拳:

  1. 访问http://localhost/dify/重定向过多
  2. 有时变成404
  3. 退回官方端口8085后又是502
  4. docker compose报找不到配置文件
  5. 重建 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 ps

2)重定向过多(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

常见原因:

  1. 自定义 nginx 没proxy_pass,在容器默认 html 目录找/dify/index.html
  2. BASE_PATH配了,但请求没打到对应路径
  3. 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 web

5)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 -d

6)容器名 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-proxy

Step 2:清掉被污染的 web,交还给 compose

docker rm -f docker-web-1

Step 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.yamlweb.environment没有硬编码172.18.x.x

Step 4:用正确 profile 拉起数据库和向量库

docker compose --profile postgresql --profile weaviate --profile collaboration up -d

Step 5:重建关键链路

docker compose up -d --force-recreate api web nginx

Step 6:验收

docker compose ps curl -I http://localhost:8085/

成功信号:

HTTP/1.1 307 Temporary Redirect location: /install

或登录页 200。然后用无痕窗口打开,避免旧 301/308 被浏览器缓存。


五、如果必须挂在子路径/dify(一般不建议)

只有在"同一域名多系统共存"时才考虑。要同时满足:

  1. Nginx不要再对/dify强制补/
  2. proxy_pass原样转发,不要二次改写路径制造双斜杠规则
  3. 前后端 base path 一致
  4. 用 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 改写回官方根路径
502nginx upstream IP 过期或 web 挂recreate nginx/web
500没启 postgres加 postgresql profile
Conflictdocker run 污染docker rm -f后交给 compose
compose not found目录不对dify/docker

最终稳妥访问方式:

http://localhost:8085

先把官方栈跑绿,再谈换端口、换局域网 IP、换域名。

换地址请看系列文:《Dify 本地部署改局域网访问:避开 4 大坑,一次配对》。