:打包分发与离线安装——插件如何打包签名、分发与离线安装?)
Dify 插件开发实验11打包分发与离线安装——插件如何打包签名、分发与离线安装Dify 实验系列 · 插件开发 11/12 | 实验编号DIFY-106-11基于 Dify 1.16.1 实测2026-081. 业务场景先讲一个我们实际遇到的场景。客服工单 SaaS 的插件集开发完了01 的时间工具、02 的工单查询、04 的企业对接……九个插件各司其职。但交付的客户环境是离线内网——不能访问 marketplace不能访问外网 PyPI安装升级全靠本地 .difypkg 文件。交付物不再是一堆代码而是一组签名包 安装顺序说明 升级方案客户环境装完要能正常跑升级不能破坏已有应用出了问题还得能回滚。我们第一次做这种交付时第一反应也是「打包上传客户自己装不就行了」。真正动手才发现——「插件能跑」和「插件能交付」是两回事离线环境装不上、升级把客户已配置的工作流弄坏了、升级失败没法回滚任何一环出问题前面十篇的开发成果都交付不出去——可靠性不在开发环境而在客户环境。这不是个例。任何 ToB 交付场景都是这个模式客户内网环境、不能访问公网市场、安装升级的可靠性直接决定交付质量——「插件能跑」只是第一步「插件能交付」才是分水岭。2. 场景痛点这个流程的痛点在离线交付时体现得最直接客户环境离线不能访问 marketplace 在线安装插件只能靠本地 .difypkg 导入——离线安装链路不跑通交付直接卡死。升级破坏已有应用插件升级后已配置旧工具的工作流会不会失配不敢升版本就永远停在 0.0.1。回滚无预案升级失败怎么办没有预案就只能现场救火客户环境越拖越糟。版本信息错乱manifest、meta、pyproject 三处版本号不同步客户控制台看到的版本信息乱七八糟售后解释不清。本质上交付的可靠性不在开发环境而在客户环境——离线安装、升级兼容、可回滚这三件事是插件交付的及格线。3. 方案为什么是 difypkg 生命周期管理选 difypkg 生命周期管理我们实际对比过打包签名规范.difypkg 打包 第三方签名白名单公钥离线环境本地导入即可安装签名校验保证包可信plugin_id 匹配升级应用依赖按 plugin_id 匹配非严格 sha——实测升级后旧应用自动兼容无需重配升级不再可怕保留旧包即可回滚装回旧版本原包即回滚回归冒烟验证恢复——回滚有预案升级才敢做。这篇文章我们就用它把 106-01~10 的插件整理为「客服工单插件集」模拟交付到离线客户环境跑通 打包 → 签名 → 离线安装 → 升级 0.0.1→0.1.0 → 回滚 的完整生命周期。4. 整体架构【客户环境离线】控制台「插件」本地导入 .difypkg签名校验白名单公钥installtasks 轮询 success回归冒烟106-01 应用作回归基线升级 0.0.1 → 0.1.0卸载旧 装新已有应用自动兼容回滚装回 0.0.1 原包回归恢复【开发环境】插件集9 插件打包 签名dify106_key.signed.difypkg链路很清晰开发环境打包签名 → 客户环境本地导入 → 签名校验安装 → 回归冒烟 → 升级/回滚闭环。关键设计是「回归基线」——106-01 应用作为每次安装/升级/回滚后的冒烟基线任何一步破坏功能都能立刻暴露。5. 模块设计5.1 打包元数据三处同步manifest.yaml 的 version、meta.version、pyproject.toml 的 version 三处必须一致客户控制台才显示清晰信息# manifest.yaml —— 打包产物元数据客户控制台可见name:dify106_01_time_toolversion:0.1.0# ① manifest versionmeta:version:0.1.0# ② meta.version升级 0.0.1 → 0.1.0 时与 ① 同步③ pyproject.toml 的version 0.1.0与上面两处保持一致——三处任一遗漏安装/升级时版本信息错乱实测坑。5.2 版本切换流程升级/回滚实测路径# 升级 0.0.1 → 0.1.0同一 plugin_id 同时只能有一个版本 → 升级 卸载旧 装新dify plugin uninstall--installation_id旧实例 id# 卸载旧用 installation_id不是 plugin_installation_id# 上传 dify106_01_time_tool-0.1.0.signed.difypkg新 sha/新版本号# 控制台插件 → 本地导入 → install → tasks 轮询 success# 106-01 应用回归冒烟回归基线# 回滚保留 0.0.1 原包 → 装回即回滚 → 回归冒烟验证5.3 升级兼容性本实验最重要结论应用依赖按plugin_id 匹配非严格 sha——插件升级后已配置旧工具的工作流自动兼容无需重配实测依赖 0.0.1 旧 uid 的应用在 0.1.0 下运行正常。但同一 plugin_id 同时只能有一个版本装 0.1.0 时 0.0.1 被替换/需先卸载。6. 运行验证验证项场景预期结果打包插件集 9 个 .difypkg命名/版本语义化规范✅ 0.0.1/0.1.0干净安装卸载 01/02/04 → 按清单装回全部 success✅回归冒烟106-01 应用装回后功能正常回归基线✅升级0.0.1 → 0.1.0新增 format 参数升级成功且已有应用不破坏✅ 旧应用自动兼容plugin_id 匹配回滚装回 0.0.1回归恢复基线✅离线安装控制台本地导入 .difypkgupload → 签名校验 → install → tasks 全链路✅在线 vs 离线差异表来源——marketplace 官方市场需外网/ 本地 .difypkg校验——官方签名 / 第三方签名白名单公钥更新——市场检查更新 / 手动升级卸载装新依赖——daemon 自动处理 / 同上需 PyPI 可达或预置缓存适用——公网环境 / 内网客户环境。7. 实战坑坑现象修复依赖声明缺失插件依赖 sdk 版本pyproject 锁 dify_plugin0.7.4,0.8客户环境由 daemon uv sync 处理完全离线环境需预置依赖daemon uv-cache 或内网 PyPI 镜像——记录为离线边界升级破坏已有应用担心升级后旧工作流失配实测应用依赖按 plugin_id 匹配非严格 sha升级后旧应用自动兼容无需重配同一 plugin_id 同时只能一个版本升级卸载旧装新回滚无预案升级失败不知如何恢复保留旧版本原包即可回滚装回旧包→ 回归冒烟验证0.1.0→0.0.1 实测恢复打包元数据不全manifest/pyproject 版本号不同步控制台版本信息错乱版本号三处同步manifest version meta.version pyproject version0.1.0 升级时三处一致离线校验失败本地导入 .difypkg 报 bad signature 拒绝白名单公钥前置配置dify106_key.public.pem 随交付包提供8. 实验文档及源码获取实验文档DIFY-106-11打包分发与离线安装.md回归基线应用 DSLdify106_01_验证应用.yml0.1.0 升级包随交付包提供插件安装包dify106_01_time_tool.signed.difypkg批次交付说明dify-106/delivery/_交付说明.md源码目录dify-106/dsl | dify-106/plugins文章聚焦核心配置与采坑点完整分步操作与升级/回滚全流程验证记录见实验文档原文。下一篇Dify 插件开发实验12企业级交付验收——插件交付如何做验收 你在这个实验的场景里踩过什么坑欢迎评论区分享你的实战经验。