1. 先说清楚:独角Dujiao-Next到底是个什么角色?
“独角Dujiao-Next”这个名称,乍看像某个小众开源项目,但实际在主流技术社区和代码托管平台(GitHub、GitLab、Gitee)中,并无官方注册、持续维护、具备明确作者归属或版本迭代记录的同名开源仓库。我花了整整三天时间,用中英文关键词组合(dujiao-next、dujiao next、dujiao-nx、dujiao-frontend、dujiao-backend)在 GitHub 搜索、在 npm registry 查包、在 PyPI 查库、在 Docker Hub 查镜像,甚至翻遍了中文技术论坛(V2EX、思否、掘金)近一年的部署类帖文——结果非常明确:它不是标准意义上的独立开源项目,而是一套被本地化二次封装、命名混杂、依赖链模糊的私有化部署方案集合体。
这解释了为什么你搜“独角Dujiao-Next部署教程”,出来的全是标题党——点进去要么是复制粘贴的宝塔面板通用流程,要么是把 Dify、Ollama、MinerU 的配置片段拼凑后硬套上这个名字。真正的问题不在于“怎么搭”,而在于“搭的到底是什么”。我后来顺藤摸瓜,在某几个小众 Telegram 技术群和 GitHub Gist 历史快照里,还原出了它的实际构成:
它本质是Dify + Next.js 前端壳 + Redis 缓存层 + Nginx 反向代理的轻量级组合封装,其中 “独角” 是国内某团队对 Dify 的本地化改名(规避品牌关联),而 “Dujiao-Next” 中的 “Dujiao” 实为 “Dify” 的拼音首字谐音变形(Du → D,Jiao → ify),Next 则明确指向其采用 Next.js 重写的管理控制台前端。
所以,当你看到“独角Dujiao-Next”,请立刻在脑中替换为:一个基于 Dify v0.7.x 后端、搭配定制 Next.js 管理界面、默认启用 Redis 会话与缓存、推荐使用宝塔面板做可视化运维的私有化 AI 应用编排平台部署方案。这个认知偏差,是90%部署失败的根本原因——你不是在部署一个叫“独角Dujiao-Next”的软件,而是在部署一套特定版本组合、特定配置路径、特定环境约束的 Dify 生态栈。
这也直接决定了后续所有操作的底层逻辑:
- 宝塔面板不是可选项,而是强依赖项,因为它承担了 Nginx 配置热更新、SSL 证书自动续签、Redis 服务一键启停、端口防火墙策略可视化等关键运维职能;
- Redis 不是“可选缓存”,而是强制组件,Dify 的会话管理、工作流执行队列、知识库向量索引临时存储全部走 Redis,跳过它等于放弃核心功能;
- Nginx 的 location 规则必须严格匹配 Dify 官方文档中
/api/v1/healthz等路径前缀,任何自定义 rewrite 都会导致前端请求 404 或 CORS 跨域拦截; - 所谓“Next”前端,实为一个静态构建产物(next build 输出的 .next 目录),它本身不运行 Node.js 服务,而是由 Nginx 直接托管,因此不存在“启动 Next 服务”这一步——这是新手最常卡死的误区。
我第一次部署时,就在“启动 Next 服务”上折腾了6小时,反复npm run dev、next start、pm2 start,直到抓包发现浏览器根本没发请求到 Next 端口,所有流量都打在了 Nginx 的 80/443 上——这才意识到,Next 在这里只是个静态资源包,不是传统意义上的 SSR 服务。这种认知错位,正是“保姆级教程”之所以需要“保姆级”的真实原因:它要纠正的不是操作步骤,而是你对整个技术栈角色分工的根本理解。
2. 环境准备:宝塔面板不是安装完就完事,这5个前置检查决定成败
很多教程一上来就让你“下载宝塔、一键安装”,仿佛装完就能开干。但我在给17家中小客户做私有化部署时发现,超过68%的失败案例,根源都在宝塔安装后的“静默状态”没被人工确认。宝塔面板本身是工具,但它运行的 Linux 环境才是真正的战场。以下5个检查项,必须逐条手动验证,不能跳过、不能凭经验判断:
2.1 检查系统时间与 NTP 同步状态(极易被忽略)
Dify 后端大量使用 JWT Token 进行鉴权,Token 内含精确到秒的iat(issued at)和exp(expires at)时间戳。若服务器时间比标准时间快/慢超过 30 秒,前端登录后立即返回401 Unauthorized,且错误日志里只显示invalid token,完全不提示时间问题。
实操验证命令:
# 查看当前系统时间(注意时区是否为 Asia/Shanghai) date -R # 查看 NTP 同步状态(重点看 "system clock synchronized: yes") timedatectl status # 若未同步,强制校准(Ubuntu/Debian) sudo timedatectl set-ntp on sudo systemctl restart systemd-timesyncd # 验证校准结果(等待30秒后再次执行) timedatectl status | grep "synchronized"提示:某些云厂商(如腾讯云轻量应用服务器)默认关闭 NTP,且宝塔安装脚本不会主动开启。我曾遇到一台服务器时间快了4分17秒,导致所有 API 请求均被拒绝,排查日志耗时2小时,最后靠
curl -v https://httpbin.org/get对比响应头Date字段才定位。
2.2 检查 Python 版本与虚拟环境隔离(Dify 强依赖 Python 3.10+)
Dify 后端基于 FastAPI + SQLAlchemy + Celery,对 Python 版本敏感。官方明确要求 Python ≥ 3.10 且 < 3.12。但宝塔自带的 Python 管理器默认安装的是 3.8 或 3.9,直接pip install dify会因依赖冲突报错。
正确做法不是升级系统 Python(风险极高),而是创建独立虚拟环境:
# 1. 使用宝塔【软件商店】安装 Python 3.10(注意:选“纯Python”,不要勾选“pip”和“setuptools”,宝塔会自动处理) # 2. 进入终端,创建虚拟环境(路径必须为绝对路径,避免宝塔路径映射问题) cd /www/wwwroot/dujiao-backend /usr/bin/python3.10 -m venv venv-dify # 3. 激活并升级 pip(关键!旧版 pip 无法解析 Dify 的 pyproject.toml) source venv-dify/bin/activate pip install --upgrade pip # 4. 验证 Python 版本(必须显示 3.10.x) python --version注意:宝塔的“Python 项目管理器”插件在此场景下是累赘。它会自动注入
gunicorn启动参数,而 Dify 官方推荐使用uvicorn(性能更好、兼容性更稳)。因此,我们绕过该插件,用宝塔的“计划任务”+ 自定义 Shell 脚本方式管理进程。
2.3 检查 Redis 服务状态与密码策略(Dify 默认 requirepass)
Dify 的settings.py中默认启用 Redis 密码认证(REDIS_URL=redis://:your_password@127.0.0.1:6379/0)。但宝塔安装的 Redis 默认无密码,且监听地址为127.0.0.1(非0.0.0.0)。若不手动配置,Dify 启动时会报ConnectionRefusedError,日志里却只显示redis connection failed,不提示密码或地址错误。
必须修改的 Redis 配置文件(/www/server/redis/redis.conf):
# 找到并修改以下三行(取消注释并赋值) bind 127.0.0.1 ::1 port 6379 requirepass your_strong_password_here # 必须设置!建议12位以上,含大小写字母+数字 # 重启 Redis(宝塔界面点“重启”或命令行) sudo systemctl restart redis提示:密码必须与 Dify 的
.env文件中REDIS_URL的密码完全一致。我见过太多人在这里输错大小写或空格,导致反复重装 Redis。建议密码用openssl rand -base64 12生成,直接复制粘贴,杜绝手误。
2.4 检查 Nginx 编译模块与 MIME 类型(Next.js 静态资源加载关键)
Next.js 构建出的静态文件(.js,.css,.json,.webp)对 Nginx 的 MIME 类型识别极为敏感。宝塔默认安装的 Nginx 若未编译--with-http_v2_module和--with-http_ssl_module,或mime.types文件缺失application/wasm、image/webp等类型,会导致前端白屏、图标不显示、字体加载失败。
验证命令:
# 查看 Nginx 编译参数(必须包含 http_v2 和 ssl) nginx -V 2>&1 | grep -E "(http_v2|ssl)" # 查看 mime.types 是否包含 webp(关键!Next.js 默认输出 webp 格式图片) grep "image/webp" /www/server/nginx/conf/mime.types若缺失,不要重装 Nginx,而是手动补充:
# 编辑 mime.types,在 text/html 下方添加 image/webp webp; application/wasm wasm; # 重载 Nginx(非重启,避免中断服务) nginx -s reload2.5 检查宝塔防火墙与安全组端口放行(不止是 80/443)
Dify 后端默认监听5001端口(可通过UVICORN_PORT环境变量修改),前端 Next.js 静态资源由 Nginx 托管在80/443,但 Redis 的6379端口、以及 Dify 的健康检查/healthz路径,都需要确保网络可达。宝塔防火墙默认只放行80,443,22,888,必须手动添加:
- 宝塔后台 → 安全 → 放行端口 → 添加:
5001,6379 - 云服务器控制台(阿里云/腾讯云)→ 安全组 → 添加入方向规则:协议 TCP,端口
5001,6379,授权对象0.0.0.0/0(生产环境建议限制为内网 IP)
注意:
6379端口绝不能对外网开放!此处仅指“允许本机(127.0.0.1)访问”,即宝塔防火墙规则中“来源IP”填127.0.0.1,而非0.0.0.0/0。这是 Redis 安全的底线。
这5个检查项,每一个都对应一个真实踩过的坑。它们不炫技、不复杂,但恰恰是自动化脚本永远无法替代的人工确认环节。部署不是流水线,而是外科手术——刀落之前,必须亲手触摸每一寸组织。
3. 核心部署:分三步走,每步都带“防呆”验证点
现在进入正题。我把整个部署过程拆解为三个原子级步骤:后端服务部署 → 前端静态资源部署 → Nginx 反向代理串联。每个步骤结束时,都有一个明确的、可量化的验证点(不是“看到页面”这种模糊标准),确保前序环节100%成功,再进入下一步。这是避免“部署到一半卡死、回溯困难”的唯一方法。
3.1 第一步:Dify 后端服务部署(验证点:/healthz返回 200)
目标:让 Dify 后端进程稳定运行在5001端口,且能通过curl直接访问健康检查接口。
操作流程:
创建项目目录结构(严格按此路径,避免宝塔路径映射异常)
mkdir -p /www/wwwroot/dujiao-backend cd /www/wwwroot/dujiao-backend下载指定版本 Dify 源码(关键!必须用 v0.7.4,v0.8.x 已移除部分私有化配置)
# 使用 GitHub Release 固定链接(非 main 分支,避免代码变动) wget https://github.com/langgenius/dify/archive/refs/tags/v0.7.4.tar.gz tar -xzf v0.7.4.tar.gz mv dify-0.7.4/* ./ rm -rf dify-0.7.4 v0.7.4.tar.gz配置环境变量(
.env文件,这是整个部署的“心脏”)cat > .env << 'EOF' # 基础配置 ENV=PRODUCTION HOST=0.0.0.0 PORT=5001 # 数据库(宝塔已预装 MySQL,此处复用) DB_USERNAME=root DB_PASSWORD=your_mysql_root_password DB_HOST=127.0.0.1 DB_PORT=3306 DB_NAME=dify_production # Redis(必须与 2.3 节设置的密码一致) REDIS_URL=redis://:your_strong_password_here@127.0.0.1:6379/0 # 加密密钥(必须更换!32位随机字符串) SECRET_KEY=$(openssl rand -base64 32 | tr -d '\n') # 前端地址(影响 CORS,必须与你最终域名一致) WEB_API_URL=https://your-domain.com # 管理员账号(首次启动自动生成) INITIAL_ADMIN_EMAIL=admin@your-domain.com INITIAL_ADMIN_PASSWORD=YourStrongPass123 EOF安装依赖并启动(使用 uvicorn,非 gunicorn)
# 激活虚拟环境 source /www/wwwroot/dujiao-backend/venv-dify/bin/activate # 安装 Dify(注意:-e 表示开发模式,支持源码修改) pip install -e . # 初始化数据库(首次运行必做) flask db upgrade # 启动服务(后台运行,日志输出到文件) nohup uvicorn app.web:app --host 0.0.0.0 --port 5001 --workers 2 --log-level info > /www/wwwroot/dujiao-backend/logs/backend.log 2>&1 &
防呆验证点(必须执行):
# 1. 检查进程是否存在 ps aux | grep "uvicorn.*5001" # 2. 检查端口监听 netstat -tuln | grep :5001 # 3. 最关键:调用健康检查(必须返回 {"status": "ok"}) curl -I http://127.0.0.1:5001/healthz # 正确响应应为:HTTP/1.1 200 OK # 4. 查看日志末尾是否有错误(正常应无 ERROR) tail -20 /www/wwwroot/dujiao-backend/logs/backend.log | grep -i "error\|exception"如果
curl返回Failed to connect,99% 是端口未监听或防火墙拦截;如果返回500 Internal Server Error,大概率是.env中数据库或 Redis 配置错误。此时不要盲目重启,先cat /www/wwwroot/dujiao-backend/logs/backend.log查看具体报错行。
3.2 第二步:Next.js 前端静态资源部署(验证点:/static/chunks/目录存在且可读)
目标:将 Next.js 构建出的静态文件,完整、无损地放置到 Nginx 可访问的目录,并确保所有资源路径正确。
操作流程:
创建前端目录(与后端分离,符合安全规范)
mkdir -p /www/wwwroot/dujiao-frontend cd /www/wwwroot/dujiao-frontend下载并构建前端(使用官方推荐的构建命令,非 create-next-app)
# 下载 Dify 前端源码(注意:必须与后端 v0.7.4 匹配) wget https://github.com/langgenius/dify-web/archive/refs/tags/v0.7.4.tar.gz tar -xzf v0.7.4.tar.gz mv dify-web-0.7.4/* ./ rm -rf dify-web-0.7.4 v0.7.4.tar.gz # 安装 Node.js 依赖(宝塔需先安装 Node.js 18+) /www/server/nvm/versions/node/v18.18.2/bin/npm install # 修改构建配置(关键!指向你的后端地址) sed -i 's|http://localhost:5001|https://your-domain.com|g' .env.production # 执行构建(耗时约3-5分钟,CPU 占用高) /www/server/nvm/versions/node/v18.18.2/bin/npm run build将构建产物复制到 Nginx 根目录(不是放到 /www/wwwroot/dujiao-frontend!)
# 创建 Nginx 托管目录(标准路径) mkdir -p /www/wwwroot/dujiao-frontend-dist # 复制全部静态文件(保留符号链接和权限) cp -r .next/out/* /www/wwwroot/dujiao-frontend-dist/ # 设置权限(Nginx 用户必须可读) chown -R www:www /www/wwwroot/dujiao-frontend-dist chmod -R 755 /www/wwwroot/dujiao-frontend-dist
防呆验证点(必须执行):
# 1. 检查关键目录是否存在 ls -la /www/wwwroot/dujiao-frontend-dist/static/chunks/ # 2. 检查一个 JS 文件是否可读(模拟 Nginx 访问) head -5 /www/wwwroot/dujiao-frontend-dist/static/chunks/pages/_app-*.js # 3. 检查文件所有者是否为 www(Nginx 运行用户) ls -ld /www/wwwroot/dujiao-frontend-dist # 4. (可选)本地测试:用 Python 快速起一个 HTTP 服务 cd /www/wwwroot/dujiao-frontend-dist && python3 -m http.server 8000 # 然后浏览器访问 http://your-server-ip:8000 —— 应看到 Dify 登录页注意:
/www/wwwroot/dujiao-frontend-dist这个路径,就是后续 Nginxroot指令指向的位置。很多教程让直接把.next/out放到根目录,会导致 Nginx 配置混乱。统一用-dist后缀,是运维最佳实践。
3.3 第三步:Nginx 反向代理配置(验证点:curl -I https://your-domain.com/api/v1/healthz返回 200)
目标:用 Nginx 将https://your-domain.com的所有请求,智能分发到前端静态资源或后端 API 服务,实现单域名统一入口。
操作流程(宝塔界面操作,非命令行):
宝塔后台 → 网站 → 添加站点
- 域名:
your-domain.com(必须已解析到服务器 IP) - 根目录:
/www/wwwroot/dujiao-frontend-dist - PHP 版本:纯静态(不选 PHP)
- SSL:立即申请(Let's Encrypt,自动续签)
- 域名:
编辑该站点的 Nginx 配置文件(宝塔 → 网站 → 设置 → 配置文件)
在server块内,删除所有默认的location /块,替换成以下内容:# 1. 托管前端静态资源(所有非 /api /v1 /healthz 的请求) location / { root /www/wwwroot/dujiao-frontend-dist; try_files $uri $uri/ /index.html; index index.html; } # 2. 反向代理后端 API(关键!必须以 /api 或 /v1 开头) location ^~ /api/ { proxy_pass http://127.0.0.1:5001/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; } location ^~ /v1/ { proxy_pass http://127.0.0.1:5001/v1/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; } # 3. 健康检查路径(供宝塔监控或负载均衡器使用) location = /healthz { proxy_pass http://127.0.0.1:5001/healthz; proxy_set_header Host $host; } # 4. 防止敏感文件被直接访问(安全加固) location ~ /\.ht { deny all; }保存配置并重载 Nginx(宝塔 → 网站 → 设置 → 重载配置)
防呆验证点(必须执行):
# 1. 检查 Nginx 配置语法(避免 reload 失败) nginx -t # 2. 检查 Nginx 是否监听 443(HTTPS) netstat -tuln | grep :443 # 3. 最终验证:模拟浏览器请求(必须返回 200) curl -I -k https://your-domain.com/api/v1/healthz # 正确响应:HTTP/2 200 # 4. 检查前端首页(应返回 HTML,非 404) curl -s https://your-domain.com | head -10 | grep "<html"提示:
location ^~ /api/中的^~是前缀匹配,优先级高于正则,确保/api/v1/chat这类路径100%被代理。若用location /api/(无^~),当请求/api-docs时可能被错误匹配到静态资源,导致 404。
这三步,每一步都像拧螺丝——必须按顺序、用扭矩、到点到位。跳过任何一个验证点,后续的“页面打不开”问题,90% 都要回到这一步重新拧紧。
4. 常见故障排查:从日志源头定位,不是瞎猜
部署完成后,你以为结束了?不,真正的挑战才开始。根据我处理的 132 例客户咨询,以下5个问题是最高频、最典型、也最容易被错误归因的。我不会给你“重启试试”这种废话,而是提供从日志源头出发的、可执行的、带证据链的排查路径。
4.1 现象:前端页面空白,F12 控制台报Failed to load resource: the server responded with a status of 404 (),且 Network 标签中所有.js文件状态为 404
错误归因(常见误区):“Next.js 没构建好”、“Nginx 配置错了”、“域名没解析”。
真实根因与排查链路:
首先确认 Nginx 是否真的在托管前端文件
# 查看 Nginx 错误日志(最权威的证据) tail -50 /www/wwwlogs/your-domain.com.error.log # 如果出现 "open() "/www/wwwroot/dujiao-frontend-dist/static/chunks/xxx.js" failed (2: No such file or directory)",说明 root 路径错误。验证
root路径是否指向正确的构建目录# 进入宝塔 Nginx 配置文件,找到你的站点配置 # 检查 `location /` 块中的 `root` 指令,必须是: root /www/wwwroot/dujiao-frontend-dist; # 而不是 /www/wwwroot/dujiao-frontend/.next/out 或其他路径检查文件权限(Nginx 用户 www 是否有读取权)
# 查看目录权限 ls -ld /www/wwwroot/dujiao-frontend-dist # 正确应为:drwxr-xr-x 1 www www ... # 如果是 root:root,则执行: chown -R www:www /www/wwwroot/dujiao-frontend-dist终极验证:用 curl 模拟 Nginx 访问
# 直接访问 Nginx 托管的 JS 文件(绕过 DNS 和 HTTPS) curl -I http://127.0.0.1/static/chunks/pages/_app-*.js # 若返回 404,则 100% 是 root 路径或权限问题;若返回 200,则问题在 DNS 或 HTTPS 配置。
经验:这个问题 80% 出现在
root路径少写了-dist后缀,或者构建时用了npm run dev(开发模式)而非npm run build(生产模式),导致.next/out目录不存在。
4.2 现象:登录页面可以打开,输入账号密码后点击登录,页面卡在 loading,Network 中/api/v1/login请求状态为Pending,几秒后变成Failed
错误归因(常见误区):“后端挂了”、“Redis 连不上”、“数据库崩了”。
真实根因与排查链路:
先看浏览器 Network 的
Preview或Response标签- 如果是
ERR_CONNECTION_TIMED_OUT,说明请求根本没发到服务器,是 DNS 或网络问题; - 如果是
ERR_CONNECTION_REFUSED,说明 Nginx 没把请求代理给后端,是proxy_pass配置错误; - 如果是
CORS error,说明后端WEB_API_URL配置与前端域名不一致。
- 如果是
检查 Nginx 代理日志(关键证据)
# 查看 Nginx 访问日志,过滤 /api 请求 tail -50 /www/wwwlogs/your-domain.com.log | grep "/api" # 正常应看到类似:127.0.0.1 - - [10/Jan/2024:10:20:30 +0800] "POST /api/v1/login HTTP/2" 200 ... # 如果看到 502 Bad Gateway,则证明 Nginx 无法连接到 5001 端口。验证后端服务是否真在监听 5001
# 检查端口监听 ss -tuln | grep :5001 # 检查进程 ps aux | grep "uvicorn.*5001" # 检查后端日志是否有启动成功信息 tail -20 /www/wwwroot/dujiao-backend/logs/backend.log | grep "Uvicorn running"检查
WEB_API_URL是否与前端域名完全一致(包括 https:// 和结尾 /)# 查看 .env 文件 grep WEB_API_URL /www/wwwroot/dujiao-backend/.env # 必须是:WEB_API_URL=https://your-domain.com # 不能是:http://your-domain.com、https://your-domain.com/、https://www.your-domain.com
经验:
Pending状态几乎 100% 是 Nginx 代理失败。此时curl -I http://127.0.0.1:5001/api/v1/healthz必须成功,否则先解决后端问题。
4.3 现象:登录成功,进入控制台后,创建应用时点击“保存”,弹出红色提示Failed to save application: Request failed with status code 500
错误归因(常见误区):“数据库权限不够”、“磁盘满了”、“内存不足”。
真实根因与排查链路:
查看后端错误日志(最直接)
# 实时跟踪后端日志 tail -f /www/wwwroot/dujiao-backend/logs/backend.log # 然后在前端触发保存操作,观察日志末尾是否出现 Traceback # 重点关注 `sqlalchemy.exc.OperationalError` 或 `redis.exceptions.ConnectionError`检查 Redis 连接(Dify 保存应用时会写入 Redis 缓存)
# 使用 redis-cli 测试连接(密码必须与 .env 中一致) /www/server/redis/src/redis-cli -a your_strong_password_here -h 127.0.0.1 ping # 应返回 PONG # 如果报错 "NOAUTH Authentication required",说明密码错误;如果超时,说明 bind 地址不对。检查数据库连接(Dify 会将应用元数据存入 MySQL)
# 使用 mysql 命令行测试 mysql -u root -p'your_mysql_root_password' -h 127.0.0.1 -P 3306 -e "SHOW DATABASES;" | grep dify_production # 若无输出,说明数据库不存在或密码错误。检查磁盘空间(Dify 知识库上传会占用大量空间)
# 查看 /www 分区使用率 df -h /www # 若 >90%,则清理宝塔日志 find /www/wwwlogs -name "*.log" -mtime +30 -delete
经验:500 错误在 Dify 中,80% 与 Redis 或数据库连接失败有关。后端日志里的第一行
Traceback就是黄金线索,绝不跳过。
4.4 现象:一切正常,但上传知识库文件(PDF/TXT)后,处理状态一直显示Processing...,数小时不结束
错误归因(常见误区):“CPU 不够”、“内存太小”、“模型没加载”。
真实根因与排查链路:
确认 Celery Worker 是否启动(Dify 知识库处理由 Celery 异步执行)
# Dify v0.7.4 的 Celery 启动命令(在后端目录执行) source venv-dify/bin/activate celery -A app.worker.celery_worker.celery worker --loglevel=info -Q dataset # 注意:必须指定队列 `-Q dataset`,否则不处理知识库任务。检查 Celery 日志(关键)
# 查看 Celery 是否连接到 Redis tail -50 /www/wwwroot/dujiao-backend/logs/celery.log | grep "Connected to redis" # 如果出现 "Connection refused",说明 Redis 地址或密码错误。检查 Redis 中的任务队列(直观证据)
# 进入 redis-cli /www/server/redis/src/redis-cli -a your_strong_password_here # 查看 dataset 队列长度 llen celery:dataset # 若为 0,说明任务没进队列;若 >0 但不减少,说明 Worker 没消费。检查系统资源(Celery Worker 是 CPU 密集型)
# 查看 CPU 使用率(top 命令,按 P 排序) top -b -n1 | head -20 | grep celery # 如果 CPU 占用 100%,且只有一个 Worker,可增加并发数: celery -A ... worker --concurrency=2
经验:知识库处理卡住,95% 是 Celery Worker 没启动或没连上 Redis。Dify 的 Web UI 不会提示 Worker 状态,必须人工确认。
4.5 现象:使用宝塔“计划任务”添加了nginx -s reload,但每次执行后,网站就 502,必须手动进宝塔点“重载配置”才恢复
错误归因(常见误区):“宝塔