如何彻底修改 Dify 默认 80 端口
在部署 AI 应用开发平台时,端口冲突几乎是每个工程师都会遇到的“第一道坎”。Dify 作为当前热门的开源 LLM 应用构建平台,默认使用 80 和 443 端口提供 Web 服务。但现实往往没那么理想:你可能已经运行了 Nginx,或者云服务器的安全组策略不允许开放标准 HTTP 端口——这时候,改端口就成了刚需。
可问题来了:很多人改完docker-compose.yaml后以为万事大吉,结果发现页面能打开,API 却调不通;或者 API 文档里显示的地址还是http://localhost/v1,根本没带上新端口。这说明什么?配置改得不彻底。
真正意义上的“彻底修改”,不只是让网页能访问,更要确保前后端通信、接口文档生成、OAuth 回调等全链路都统一使用新端口。下面我们就一步步拆解,如何从底层到应用层完整迁移 Dify 的默认端口。
进入 Dify 项目根目录下的docker文件夹是第一步:
cd ./dify/docker这里的docker-compose.yaml是整个服务编排的核心。找到nginx服务的ports配置段:
services: nginx: image: nginx:alpine ports: - '${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}' - '${EXPOSE_NGINX_SSL_PORT:-443}:${NGINX_SSL_PORT:-443}' env_file: - ../.env注意这个${VAR:-default}写法,它来自 Shell 的默认值扩展语法,意思是如果环境变量未设置,则使用冒号后的默认值。也就是说,最终暴露哪个端口,其实是由.env文件控制的。
你可以直接在这里硬编码测试,比如改成:
ports: - '806:80' - '4436:443'这样宿主机的 806 端口就会映射到容器内的 80 端口。不过更推荐的做法是保留变量引用,通过.env统一管理。毕竟后期要部署多套环境(开发、测试、生产),靠改 YAML 文件显然不够灵活。
所以最佳实践是:不动 docker-compose.yaml 中的变量结构,只通过 .env 控制具体值。
接下来打开项目根目录下的.env文件:
vi .env这是整个 Dify 部署体系的“中枢神经”,所有服务的行为几乎都受它影响。
首先看 Nginx 相关的端口配置:
NGINX_PORT=80 NGINX_SSL_PORT=443 EXPOSE_NGINX_PORT=80 EXPOSE_NGINX_SSL_PORT=443其中:
NGINX_PORT是容器内部 Nginx 实际监听的 HTTP 端口;EXPOSE_NGINX_PORT是你想在宿主机上暴露的外部访问端口。
如果你只是想换个外网访问口,比如用806,而不想动容器内逻辑,那只需改后者:
EXPOSE_NGINX_PORT=806保持NGINX_PORT=80不变即可。Docker 会自动完成映射,前端代码也无需感知容器内部细节。
但如果你也希望容器内部服务运行在非标准端口上(例如避免与其他容器冲突),那就两个都改:
NGINX_PORT=806 EXPOSE_NGINX_PORT=806HTTPS 同理,若启用加密访问:
NGINX_HTTPS_ENABLED=true NGINX_SSL_PORT=4436 EXPOSE_NGINX_SSL_PORT=4436保存退出后,这些变更会在下次启动时生效。
到这里,Web 页面大概率已经可以通过http://localhost:806打开了。但别急着庆祝——真正的坑往往藏在看不见的地方。
试想这样一个场景:你在 Dify 的「开发者中心」查看 API 文档,示例请求却是这样的:
curl http://localhost/v1/workspaces/current明明你现在走的是 806 端口,为什么文档里没有体现?这是因为 Dify 前端生成 API 地址时,并不会自动识别当前页面端口是否为非标准值。它依赖几个关键环境变量来拼接 base URL。
必须手动设置以下三项:
SERVICE_API_URL=http://localhost:806 APP_API_URL=http://localhost:806 APP_WEB_URL=http://localhost:806它们各自的作用如下:
SERVICE_API_URL:用于展示在 API 文档中的基础路径,用户复制的就是这个地址。APP_API_URL:前端 JavaScript 实际发起请求的目标地址,必须可达且允许跨域(如果是不同源)。APP_WEB_URL:前端页面的公开访问地址,影响登录回调、分享链接、SSO 跳转等场景。
这三个值在单机部署时通常一致。但如果你做了反向代理,比如用 Nginx 挂了域名https://dify.example.com,那就应该写成:
SERVICE_API_URL=https://dify.example.com APP_API_URL=https://dify.example.com APP_WEB_URL=https://dify.example.com⚠️ 特别提醒:不要偷懒留空或写
localhost!一旦你的服务部署在远程服务器上,前端仍然试图连接本地,必然失败。务必根据实际访问方式填写完整协议 + 主机 + 端口。
还有一点容易忽略:.env文件必须被正确加载。检查docker-compose.yaml是否包含:
env_file: - ../.env否则变量不会注入容器,一切配置等于白搭。
改完配置不重启等于没改。回到docker目录执行:
cd ./dify/docker docker-compose down docker-compose up -d等待所有服务启动完毕,开始验证效果。
第一关:浏览器访问
http://localhost:806能看到登录页就算成功一半。如果打不开,先查三件事:
- 容器是否正常运行:
docker ps | grep nginx - 日志有没有报错:
docker logs nginx - 防火墙/安全组是否放行了 806 端口
第二关:API 文档中的 base URL。
登录后台 → 创建一个应用 → 发布 → 查看 API 文档。确认所有接口前缀都是:
http://localhost:806/v1/...而不是:
http://localhost/v1/...如果是后者,说明SERVICE_API_URL没起作用。常见原因有:
.env文件路径不对,没被读取;- 变量名拼错,比如写成了
SERIVCE_API_URL; - 修改后忘了重启服务。
第三关:真实 API 调用。
用 curl 测试一个需要认证的接口:
curl -H "Authorization: Bearer <your-token>" http://localhost:806/v1/workspaces/current/member预期返回 JSON 数据,状态码可能是200或401(未授权也算通)。如果出现Connection refused或重定向到:80,说明端口映射或反向代理配置仍有问题。
第四关:集成兼容性。
如果你正在将 Dify 的 Agent 或 Workflow 接入第三方系统(如企业微信、飞书机器人),请测试回调功能是否正常。某些系统会校验回调地址的域名和端口,变更后需重新配置白名单或签名规则。
当你顺利通过以上四轮验证,才算真正完成了端口迁移。
总结一下,完整的端口修改流程包括:
- 调整 Docker 映射端口:通过
.env控制EXPOSE_NGINX_PORT,实现外部访问切换; - 可选更新容器内监听端口:修改
NGINX_PORT,使容器内部也运行在非标准端口; - 显式声明通信地址:设置
SERVICE_API_URL、APP_API_URL、APP_WEB_URL,确保前后端链路统一; - 全链路功能验证:从页面访问到接口调用,再到外部集成,逐一确认无遗漏。
这套方法不仅适用于 80 → 806 的迁移,也能轻松应对 HTTPS 化、反向代理接入、多实例隔离等进阶需求。
小建议:把修改后的
.env文件备份下来,命名如.env.prod.port806,方便后续自动化部署或团队共享。
未来如果你想进一步提升安全性,可以结合 Nginx 反向代理 + Let’s Encrypt 免费证书,实现https://dify.yourcompany.com的专业访问方式。那时你会发现,今天这一步看似简单的端口调整,其实是通往生产级部署的关键起点。
Dify 正被越来越多企业用于构建智能客服、知识库问答、自动化内容生成等高价值 AI 应用。掌握这类底层部署细节,不仅能避开线上事故,更能让你在团队中脱颖而出——毕竟,能把系统稳定跑起来的人,永远稀缺。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考