现象:
1.现在通过有网条件下导出插件,然后在无网环境下导入,因需要pip环境的依赖,导致无法下载相关依赖报错
诉求:
1.能否各一个官方的流程或者脚本方便后续升级
针对您在公司生产环境(完全离线、禁止外网)下安装 Dify 插件遇到的依赖下载失败问题,目前官方并没有直接提供“一键生成全量离线包”的脚本,但社区和最佳实践中已经形成了一套标准的**“二次打包(Repackaging)”**流程。
您遇到的现象(导出后导入仍报错)是因为直接导出的 .difypkg 文件通常只包含插件代码,不包含运行所需的 Python (pip) 或 Node.js (npm) 依赖。在离线环境下,Dify 的插件守护进程(plugin_daemon)尝试去公网拉取这些依赖时会超时或失败。
以下是基于社区验证的标准离线安装流程攻略及自动化升级建议。
核心解决方案:使用 dify-plugin-repackaging 工具
解决思路是:在有网的机器上,利用工具将“插件源码” + “所有依赖库”重新打包成一个“胖包”(自包含依赖的 .difypkg),然后传输到离线环境安装。
1. 准备工作(在有网机器上)
您需要一台能访问外网的机器(可以是您的开发机或跳板机),并安装好 Git 和 Docker(推荐方式,避免本地 Python 环境冲突)。
步骤 1.1:获取重打包工具
社区维护了一个专门用于此场景的工具库:
git clone https://github.com/junjiem/dify-plugin-repackaging.git
cd dify-plugin-repackaging
(注:如果无法访问 GitHub,可在有网机器下载该仓库的 zip 包传入)
步骤 1.2:下载原始插件包
- 登录有网环境的 Dify 市场,或者直接从 GitHub Release 下载您需要的插件源码包/原始
.difypkg文件。- 假设下载的文件名为
my-plugin-1.0.0.difypkg。
- 假设下载的文件名为
步骤 1.3:执行重打包(关键步骤)
该工具会自动分析插件的 requirements.txt 或 package.json,下载所有依赖并注入到包中。
方式 A:使用 Docker 运行(推荐,环境最干净)
确保当前目录下有下载的插件包,执行:
# 语法:./plugin_repackaging.sh local <插件文件名>
chmod +x plugin_repackaging.sh
./plugin_repackaging.sh local ./my-plugin-1.0.0.difypkg
原理:脚本会启动一个临时容器,配置国内镜像源(如阿里云/清华源)下载依赖,然后将依赖打入新的包中。
方式 B:使用本地 Python 环境
如果您本地有 Python 3.10+ 环境:
pip install -r requirements.txt # 如果工具本身有依赖
# 然后运行脚本
./plugin_repackaging.sh local ./my-plugin-1.0.0.difypkg
步骤 1.4:获取离线包
执行成功后,当前目录下会生成一个新的文件,通常命名为类似 my-plugin-1.0.0_offline.difypkg 或覆盖原文件。
这个新包已经包含了所有必要的 wheel 文件和 node_modules,不再需要联网。
2. 离线环境部署流程
步骤 2.1:传输文件
将生成的 *_offline.difypkg 文件通过安全通道(如堡垒机文件传输、光盘等)复制到离线生产环境的服务器。
步骤 2.2:上传安装
- 登录离线环境的 Dify 控制台。
- 进入 插件 (Plugins) → 本地上传 (Local Upload)。
- 选择刚才传输进来的
_offline.difypkg文件进行安装。 - 结果:此时插件守护进程检测到包内已有依赖,将跳过
pip install步骤,直接加载成功。
针对诉求:官方流程或脚本方便后续升级
由于官方尚未内置此功能,建议您在公司内部建立一套**“插件离线构建流水线”**。
方案一:自建简易自动化脚本(推荐)
您可以将上述 dify-plugin-repackaging 过程封装为一个简单的 Shell 脚本,放在公司的有网构建服务器上。
脚本示例 (build_offline_plugin.sh):
#!/bin/bash
# 用法:./build_offline_plugin.sh <插件下载链接或本地路径>
PLUGIN_INPUT=$1
TOOL_REPO="https://github.com/junjiem/dify-plugin-repackaging.git"
WORK_DIR="./plugin_build_workspace"
# 1. 准备工具
if [ ! -d "$WORK_DIR/repackaging" ]; then
git clone $TOOL_REPO $WORK_DIR/repackaging
fi
cd $WORK_DIR/repackaging
# 2. 下载插件 (如果是链接)
if [[ $PLUGIN_INPUT == http* ]]; then
wget $PLUGIN_INPUT
PLUGIN_FILE=$(basename $PLUGIN_INPUT)
else
PLUGIN_FILE=$PLUGIN_INPUT
# 复制文件到工作区
cp ../../$PLUGIN_FILE .
fi
# 3. 执行重打包
echo "正在重打包 $PLUGIN_FILE,这将下载所有依赖..."
chmod +x plugin_repackaging.sh
./plugin_repackaging.sh local ./$PLUGIN_FILE
# 4. 输出结果
OUTPUT_FILE=$(ls -t *.difypkg | head -n 1)
echo "✅ 离线包生成成功:$WORK_DIR/repackaging/$OUTPUT_FILE"
echo "📁 请将此文件传输至离线环境安装。"
升级流程: 当需要升级插件时,只需在有网服务器运行此脚本指向新版本插件,生成的包直接替换离线环境的旧包即可。
方案二:搭建私有 PyPI/NPM 镜像(企业级长期方案)
如果公司插件数量巨大,每次重打包比较繁琐,可以考虑更彻底的架构改造:
-
搭建私有源:在离线内网搭建私有 PyPI (如
pypiserver) 和 NPM (如Verdaccio) 服务。 -
预同步依赖:在有网机器上使用
pip download -r requirements.txt和npm pack将所有可能用到的依赖下载到本地,上传至私有源。 -
修改 Dify 配置:
在离线环境的docker-compose.yaml中,为plugin_daemon服务注入环境变量,指定内部镜像源:services: plugin_daemon: environment: - PIP_INDEX_URL=http://<内网私服IP>:8080/simple - NPM_REGISTRY_URL=http://<内网私服IP>:4873注意:这需要您预先知道所有插件的依赖列表并同步到私服,维护成本较高,但一劳永逸。
常见问题排查 (Troubleshooting)
-
报错
Connection timed out或Network unreachable:- 确认您安装的是重打包后的
.difypkg文件,而不是直接从市场导出的原始文件。 - 检查
docker logs -f dify-plugin-daemon-1(容器名可能不同),确认是否还在尝试访问pypi.org。如果是,说明包内未包含依赖。
- 确认您安装的是重打包后的
-
架构不匹配 (Wheel 文件错误):
dify-plugin-repackaging默认会根据当前构建机的架构下载依赖。- 重要:请确保有网构建机器的操作系统和 CPU 架构(如 Linux x86_64)与离线生产环境完全一致。
- 如果生产环境是 ARM (如鲲鹏、Mac M系列),必须在相同架构的机器上运行重打包脚本,或者使用 Docker 指定架构运行(例如在 x86 机器上用
docker run --platform linux/arm64 ...模拟,但较复杂,建议找一台同架构的跳板机)。
-
权限问题:
- 确保离线环境下的
plugin_daemon容器有权限读取挂载的插件目录。
- 确保离线环境下的
总结
- 现状:直接导出导入行不通,因为缺依赖。
- 解决:必须使用
dify-plugin-repackaging工具在有网环境进行“二次打包”,将依赖植入包内。 - 升级策略:将此工具固化为公司内部的一个“插件构建脚本”,每次有新插件或升级时,先在构建机跑一遍脚本,产出离线包,再分发。
这是目前社区(包括 CSDN、掘金等技术博客中多位实施专家)验证过的最稳定方案。