插件安装失败,陷入无限循环,如何让安装停下来?

大家好,我在本地docker中部署了dify1.11.4。在安装通义插件的时候,陷入死循环。报错显示“Task timed out but not properly terminated”。但是安装并没有停止,而是不断重复,直至我有近百条插件安装失败记录。

我在其他话题中看到有人提到,通过提POST请求解决此问题。但是我是本地部署,没有authorization值。无法通过该步骤修复。

插件安装失败后,界面上永远显示“1 个插件安装中”

想请问大家有没有好的办法,能让安装停下来?

有其他值,问一下AI

有其他值,问一下AI

docker logs docker-plugin_daemon-1

@Dify_Forum_Helper 跟一下

可以先按下面步骤一步步排查和“刹车”,尽量不用到你说的那个需要 Authorization 的 POST 接口。


1. 先确认插件守护进程是否还在疯狂重试

在部署服务器上执行(你已经被提示过一次):

docker logs docker-plugin_daemon-1 -n 200

看一下最近日志里是不是在不断重复类似:

  • 某个插件 install 任务
  • 一直报 Task timed out but not properly terminated

如果是:

  • 很可能是某个“正在安装”的任务卡住,插件守护进程在不断重试。

为了先“刹车”,你可以暂时停掉这个容器:

docker stop docker-plugin_daemon-1

这样能先阻止继续刷新的失败安装记录。
(之后再启动:docker start docker-plugin_daemon-1


2. 不通过 POST 接口,如何拿到本地的 Authorization?

即便是本地部署,前端访问 Dify 的时候同样会带上一个 Bearer Token,只是浏览器帮你传了。

你可以这样拿到这个 token,然后再用来调用你在另一个帖子里看到的那个 POST 接口(“清理插件安装中状态”的接口):

  1. 用浏览器打开你的 Dify 网页(比如 http://localhost:3000 或你自己的域名),正常登录。
  2. 打开浏览器开发者工具:
    • Chrome/Edge:F12 → 选择「Network / 网络」标签。
  3. 在页面上随便点一个会访问后端的页面(比如进入「工作室」「应用」等)。
  4. 在 Network 面板里,找到一个请求路径类似 /console/api/... 的接口,点进去。
  5. 在「Headers / 请求头」里找到 Authorization 字段,一般是:
    Authorization: Bearer xxxxxxx...
    
  6. Bearer 后面的这一长串 token 复制出来。(注意不要泄露给别人)

这样你就有了本地部署的 Authorization 值,可以和云端一样调那个修复接口了。


3. 用拿到的 Token 调用“清理安装中任务”的接口

你在引用的帖子里应该已经看到具体的接口路径和方法了,一般是一个 POST 请求。

可以用 curl(在服务器上)来发:

curl -X POST "http://<你的后端地址>/xxx/xxx" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <你刚才复制的 token>" \
  -d '{
    // 按那篇帖子里的 body 填
  }'

注意几件事:

  • <你的后端地址>:如果你是默认的 docker-compose,一般是:
    • 在宿主机浏览器访问:http://<服务器IP>:3000
    • 但 API 真实后端端口可能是 5001/8000 等,要跟你自己的配置对上(看 docker-compose.yml 里 API 服务的映射)。
  • 接口路径、body 参数要完全按你引用的帖子来(避免误删其他记录)。

调用成功后,刷新 Dify 页面,通常:

  • 右上角「正在安装插件」的提示会消失;
  • 通义这个插件会变成「未安装」或失败状态,你可以之后再尝试重新安装(建议先排查镜像/网络问题)。

4. 如果确实无法/不想用 API,可以考虑更“硬”的方式(谨慎)

这种方式风险更高,只适合你有一定数据库操作经验、并且能接受做数据库备份:

  1. 停掉 Dify 相关容器(避免写入冲突)
    docker compose down
    
  2. 备份数据库容器中的数据(Postgres):
    • 查到 Postgres 容器名,比如 docker ps 看到 dify-postgres-1
    • pg_dump 导出:
      docker exec -t dify-postgres-1 pg_dump -U <db_user> <db_name> > dify_backup.sql
      
  3. 进入数据库,找到「插件安装任务」相关的表,把状态从 installing / pending 改成 failed 或直接删掉那条记录。

但因为不同版本表结构会有变化、字段名也不完全一样,如果你走到这一步,最好把你 docker-compose.yml 里的版本号、数据库信息、以及一段相关表结构贴出来再讨论,避免误操作。


5. 建议你现在可以先回帖做两件事

  1. 在服务器上执行:

    docker logs docker-plugin_daemon-1 -n 200
    

    把关键报错(包含 Task timed out but not properly terminated 上下几行)贴到帖子里。

  2. 按上面第 2 步,在浏览器里拿到 Authorization: Bearer ...,确认你能抓到 token,如果有疑问可以贴一张打码后的请求头截图。

有了日志 + 你的版本(1.11.4)这些信息,后续如果还卡住,可以更精确判断是不是当前版本的已知问题,还是通义插件自身安装(比如网络、Python 源、镜像)的问题。


:books: 可能对你有帮助的文档(与问题相关)

:label: 版本信息

  • 你当前是 v1.11.4,插件系统已经较为完善,但仍有插件安装/依赖安装相关问题在后续版本持续修复。如果后面官方在 Release 里提到修复类似「插件安装超时/卡在安装中」的问题,建议有条件的话也可以考虑升级。

安装插件总是失败,不管是本地安装还是市场安装都是Task timed out but not properly terminated,下面是我的docker 日志,我dify的版本是1.11.4,请帮忙看一下,感谢

@Dify_Forum_Helper 继续跟一下

这两位的情况其实已经把线索给得很全了,我帮你们汇总一下“怎么刹车 + 怎么清理 + 怎么避免再次卡死”,都针对 1.11.4。


一、你们现在遇到的现象是什么情况?

从 Niklaus1028 的日志看,大致是:

  • 不断轮询 /plugin/<plugin-id>/management/install/tasks/dispatch/model/schema 等接口;
  • 中间出现:
    • task xxx timed out
    • record not foundSELECT * FROM "plugin_declarations" WHERE plugin_unique_identifier = 'alipay/alipay_plugin:0.1.0@...'

结合 ao_zhang 的描述:

  • UI 一直显示「正在安装插件」;
  • 后台任务 Task timed out but not properly terminated
  • 同一个插件(通义 / 支付宝等)被重复创建安装任务。

这说明:

  1. 某个安装任务已经超时,但状态没有被正确标记为“结束”,导致守护进程一直认为它在安装中;
  2. 有些插件的 plugin_unique_identifier 在 DB 中查询不到(record not found),但安装流程又在继续调度,进一步把状态搞乱。

二、先“刹车”——别让守护进程继续刷任务

在你们的服务器上先停一下插件守护进程容器:

docker stop docker-plugin_daemon-1

作用:

  • 立刻停止继续创建新的安装任务、停止继续刷 Task timed out...
  • 方便你之后做清理(不然刚清完,又被新任务刷一遍)。

清理完后再启动:

docker start docker-plugin_daemon-1

三、怎么在本地部署环境拿到 Authorization(Bearer Token)

你们都是 1.11.4 的 docker-compose 自托管,即便是本地,前端访问后端也会自动带上一个 Bearer Token,只是平时看不到而已。

步骤(以 Chrome/Edge 为例):

  1. 在浏览器访问你的 Dify 管理端(例如 http://服务器IPhttp://localhost),正常登录管理员账号。
  2. F12 打开开发者工具 → 切到「Network / 网络」面板。
  3. 在页面里随便点一下别的菜单(例如进入「应用」「数据集」等),确保有接口请求被发出。
  4. 在 Network 列表里,找一个路径类似 /console/api/... 的请求,点进去。
  5. 在「Headers / 请求头」里找到:
    Authorization: Bearer xxxxxxxx...
    
  6. Bearer 后面那一长串 token 复制出来(只留给自己用,别发到论坛)。

有了这个 token,就可以在服务器上用 curl 去调用清理接口,而不需要“云端特有”的 Authorization。


四、清理“卡住的安装任务”

在之前那篇「插件安装失败后,界面上永远显示 1 个插件安装中」的帖子里,已经有一个专门的「清理安装任务状态」的 POST 接口和 body 模板,你可以按那里的说明来。

调用方式的通用写法如下(把路径和 body 换成那篇帖子里给的实际内容):

curl -X POST "http://<你的后端地址>/<那篇帖子里的接口路径>" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <上一步复制的token>" \
  -d '{
    ... 这里填那篇帖子里的 JSON body ...
  }'

注意:

  • <你的后端地址>
    • 如果你用官方的 docker 目录直接起的,一般 Nginx 把前端和后端都暴露在 80 端口,你可以直接用 http://<服务器IP> 或你现在能访问 Dify 的那个地址;
    • 如果你有自定义反向代理,请用你前端正常访问 Dify 的域名/端口。
  • 路径、请求体请完全按那篇老帖子给的来,不要自己猜,以免误删其它插件或任务状态。

调用成功后:

  • 刷新一下 Dify 页面,
    • 右上角「正在安装插件」的提示应该会消失;
    • 那个卡住的插件应变为「未安装」或者失败状态。

五、如果清理后仍然任何插件都超时,该往哪个方向排查?

你们都是 1.11.4,而且:

  • 本地安装(上传 difypkg)也超时;
  • 市场安装也超时;
  • 日志中连续 timeoutrecord not found

这通常说明不是单个插件的问题,而是插件运行环境本身不正常。几个重点方向:

1. 机器性能和 Docker 资源

插件安装会在插件容器里创建 Python 虚拟环境、下依赖,如果机器很“紧”:

  • CPU/内存不足;
  • Docker 给的资源太小;

都可能导致任务跑得很慢甚至超时。对应操作:

  • 确认机器至少有:
    • 2 核 CPU、4G+ 内存(官方最低要求建议 8G 更稳);
  • 在 Docker Desktop(如果是 Mac/Win)里适当调高 CPU / Memory;
  • 服务器上用 top/htop 观察安装时 CPU / MEM 是否打满。

2. 插件容器里访问外网 / Python 源是否通畅

从别的插件帖子来看,1.11.x 版本里很多安装失败都是因为:

  • 默认 PyPI 源连不上或非常慢;
  • 网络策略或代理挡住了插件容器访问外网。

排查:

  1. 进入插件 daemon 容器:
    docker exec -it docker-plugin_daemon-1 /bin/bash
    
  2. 在容器里试一下:
    ping pypi.org
    curl -I https://pypi.org/simple
    
    如果完全不通、或延迟极高,安装时就很容易超时。

可以考虑:

  • .env 里为插件设置国内 Python 源(如果官方在你版本支持);
  • 或在宿主机层面配置网络代理,确保容器能正常访问外网。

3. record not found 说明什么?

你日志里类似:

SELECT * FROM "plugin_declarations" WHERE plugin_unique_identifier = 'alipay/alipay_plugin:0.1.0@...' ... record not found

这说明:

  • 插件声明没有写入数据库成功;
  • 但安装流程后续步骤还在根据这个 plugin_unique_identifier 去查,得不到记录。

在你用 API 清理安装任务后:

  • 建议重新打开插件市场/插件管理页;
  • 为避免叠加旧垃圾状态,先只装一个简单插件测试(例如自带的官方演示插件):
    • 如果简单插件也超时,那就是“环境级问题”;
    • 如果简单插件 OK,而某几个特定插件失败,就集中看这些插件的依赖和网络。

六、如果 API 清理还是搞不定,只剩下“重置状态”两条路(风险高)

只在你确认数据可备份、且对数据库操作有经验时考虑:

  1. 整栈停机 + 备份数据库

    docker compose down
    

    假设 Postgres 容器叫 docker-db_postgres-1,备份:

    docker exec -t docker-db_postgres-1 \
      pg_dump -U <db_user> <db_name> > dify_backup.sql
    
  2. 进入数据库,把插件相关的“安装任务”和“安装中状态”删掉或改为失败。
    这一步不同版本表名/字段略有差异,不建议你自己猜字段名,非常容易把别的东西删错。
    如果一定要走这条路,建议你单独开一贴或在这里补充:

    • docker-compose.yml 里 Dify 版本和 Postgres 相关配置;
    • \dt 看一下插件相关表的名字和结构截图;
      然后再一起推敲具体 SQL。

七、下一步你们可以这样继续反馈,方便精确定位

建议两位分别补充这些信息到本帖:

  1. 执行:

    docker logs docker-plugin_daemon-1 -n 200
    

    把包含 Task timed out but not properly terminatedrecord not found 的那几段日志,打码后贴上来。

  2. 按上面的步骤拿到 Authorization: Bearer ...,尝试一次“清理安装任务”的 POST 调用:

    • 调用用的是哪一个接口路径?
    • 返回的 HTTP 状态码是多少(200 / 4xx / 5xx)?
    • 调用后刷新 UI,“正在安装插件”的提示是否消失?
  3. 清理后,再尝试安装一个最简单的插件,看是否仍然统一报 Task timed out but not properly terminated

只要我们能确认:

  • 清理接口能正常把卡住的任务“归零”;
  • 但新安装仍然超时;

那就基本可以判断是“环境/网络/资源”问题,而不是单纯的一次性脏数据,后面就可以针对性给环境优化的指导,或者建议考虑升级到较新版本(后续版本在插件安装超时与任务清理方面确实有持续修复)。


:books: 相关文档

如果你们方便的话,可以先按上面的“刹车 + 拿 token + 调清理接口”这三步来走一遍,然后回帖说下执行结果,我们再一起把根因缩小到“环境问题还是版本 bug”。

docker logs -f docker-plugin_daemon-1 以检查此 Docker 日志,然后重新安装它。

请问我始终找不到这个值该怎么办 :melting_face:

Authorization 这个值确实有点“藏得深”,我再按最细的步骤帮你确认一下可能遗漏的点。

下面完全不需要看任何代码或服务器日志,只在浏览器里操作即可。


先确认两件事

  1. 一定要“登录成功”之后再找

    • 你需要已经在 Dify 的正常主页里(左侧有「应用 / 工作流 / 数据集」之类菜单),
    • 不是在 /install 初始化页面。
  2. 一定要看的是接口请求,不是 HTML / 图片等静态文件


在 Chrome / Edge 中找 Authorization 的“保姆级流程”

如果你用的是 Firefox / Safari,最后也有补充。

  1. 打开 Dify 页面并登录

    • 例:http://localhosthttp://你的服务器IP
    • 输入账号密码,进入正常工作台页面。
  2. 打开开发者工具

    • 键盘按:F12
    • 或右键页面空白处 → “检查 (Inspect)”
  3. 切到「Network / 网络」这一栏

    • 顶部标签通常有:Elements / Console / Sources / Network / …
    • 一定要点进 Network / 网络
  4. 刷新页面一次(非常关键)

    • 在 Network 面板打开的情况下,按浏览器刷新按钮或 Ctrl+R / Cmd+R
    • 刷新后,Network 列表里会开始出现很多请求条目。
  5. 只筛选接口请求
    在 Network 面板上方通常有一排 filter 按钮:

    • All / Doc / JS / XHR / Fetch / Img / …
    • 请点 “XHR” 或 “Fetch”(如果有 All 也可以选 All,但 XHR / Fetch 更干净)。
  6. 找到一个路径里带 /console/api/ 的请求

    • 例如:
      • /console/api/account/profile
      • /console/api/apps
      • 或其它 /console/api/... 形式
    • 如果一眼看不到,可以在 Network 面板右上角的搜索框里输入:/console/api 过滤一下。
  7. 选中这个 /console/api/... 请求,切到 Headers / 请求头

    • 点击某一行请求 → 右侧会出现详情面板;
    • 里面有类似的几个 tab:Headers / Payload / Preview / Response;
    • 请选择 Headers(有时可能显示为“标头 / 请求头”)。
  8. 在 Headers 里找 Authorization

    • 向下翻到 “Request Headers / 请求头” 区域;
    • 找到类似这一行:
      Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
      
    • 如果找到了:
      • 双击或右键复制这一整行里的值;
      • 真正需要的是 Bearer 后面这一长串 token。

如果你还是看不到 Authorization,通常有这几种情况

情况 1:实际上没有成功登录

  • 特征:
    • 你访问的是 /install 注册页,或登录后又被跳回登录页;
    • Network 里 /console/api/account/profile 返回的是 401 (UNAUTHORIZED),
    • 这时浏览器通常不会带上登录后的 Bearer token。
  • 建议:
    • 先确认你已完成初始化和首次管理员注册;
    • 登录后页面左侧能看到完整菜单;
    • 然后再按上面的步骤找 /console/api/... 请求。

情况 2:选错了请求类型

  • 如果你点的是:
    • document 类型(HTML)、img(图片)、js(脚本),
    • 这些请求往往 没有 Authorization
  • 解决:
    • 在 Network 顶部点击 XHR / Fetch,只看接口请求;
    • 再选路径中包含 /console/api 的那几条。

情况 3:用的是 Firefox / Safari,界面略有不同

大致思路相同,只是菜单名字略不一样:

  • Firefox

    1. F12 → 选「网络 (Network)」;
    2. 刷新页面;
    3. 选中 /console/api/... 的请求;
    4. 在右侧面板找「标头 (Headers)」→ “请求标头 (Request headers)” 里的 Authorization
  • Safari(需要先在偏好设置里勾选“开发者菜单”)

    1. 菜单栏 “开发” → “显示 Web 检查器”;
    2. 选 “网络”;
    3. 方式同上。

情况 4:你在反向代理前端层看 Network(例如 Cloudflare 的调试)

  • Authorization 只会出现在 浏览器 → 你 Dify 前端域名 这一步的请求里;
  • 如果你在别的中间层(例如某个管理控制台)看流量,可能已经被隐藏或脱敏。

如果方便的话,你可以这样回帖,我们可以帮你确认

  1. 按上面的步骤操作后,在 Network 里:

    • 截一张选中 /console/api/... 请求、切到 Headers 页的截图;
    • Authorization 那一行用马赛克打掉再发上来;
    • 这样可以确认你是不是点到了“对的请求”。
  2. 告诉一下你用的浏览器和系统:

    • 例如:Chrome 122 / Edge 121,Windows 11 / macOS 等。

只要你能在 Network 里找到任何一个 /console/api/... 请求,Authorization 一定就在它的请求头里;如果我们能看到你现在看到的界面,大概率几步就能帮你 pinpoint 到。

请问我始终找不到这个值该怎么办 :melting_face:


问gpt解决了,说我前端走的cookie不会发autorization
在网页开发者工具控制台执行
`(async () => {
// 1) 从 cookie 里尝试取 csrf_token(有些版本是这个名字)
const csrfFromCookie =
document.cookie.split(‘; ‘).find(x => x.startsWith(‘csrf_token=’))?.split(’=’)[1];

// 2) 从 localStorage / sessionStorage 里兜底找(不同版本可能放这)
const csrfFromStorage =
localStorage.getItem(‘csrf_token’) ||
sessionStorage.getItem(‘csrf_token’) ||
localStorage.getItem(‘X-CSRF-Token’) ||
sessionStorage.getItem(‘X-CSRF-Token’);

const csrf = csrfFromCookie || csrfFromStorage;

if (!csrf) {
console.error(‘没找到 CSRF token。请在 Network 里随便点一个 /console/api 的请求,复制 Request Headers 里的 X-Csrf-Token 值。’);
return;
}

const res = await fetch(‘/console/api/workspaces/current/plugin/tasks/delete_all’, {
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
‘X-CSRF-Token’: decodeURIComponent(csrf), // :star:关键
},
credentials: ‘include’,
body: JSON.stringify({}),
});

const text = await res.text();
console.log(‘status:’, res.status);
console.log(‘body:’, text);
})();`

停止之后,重新执行docker start docker-plugin_daemon-1 打开后,又开始下载起来了。有办法停下来吗?

这样去解决

1.在plugins页面找到相关的token

2.调用接口即可

1 个赞