能否给一份离线环境下安装插件的流程攻略,公司生产环境都是离线,禁止访问外网的

现象:
1.现在通过有网条件下导出插件,然后在无网环境下导入,因需要pip环境的依赖,导致无法下载相关依赖报错
诉求:
1.能否各一个官方的流程或者脚本方便后续升级

针对您在公司生产环境(完全离线、禁止外网)下安装 Dify 插件遇到的依赖下载失败问题,目前官方并没有直接提供“一键生成全量离线包”的脚本,但社区和最佳实践中已经形成了一套标准的**“二次打包(Repackaging)”**流程。

您遇到的现象(导出后导入仍报错)是因为直接导出的 .difypkg 文件通常只包含插件代码,不包含运行所需的 Python (pip) 或 Node.js (npm) 依赖。在离线环境下,Dify 的插件守护进程(plugin_daemon)尝试去公网拉取这些依赖时会超时或失败。

以下是基于社区验证的标准离线安装流程攻略自动化升级建议


核心解决方案:使用 dify-plugin-repackaging 工具

解决思路是:在有网的机器上,利用工具将“插件源码” + “所有依赖库”重新打包成一个“胖包”(自包含依赖的 .difypkg),然后传输到离线环境安装。

1. 准备工作(在有网机器上)

您需要一台能访问外网的机器(可以是您的开发机或跳板机),并安装好 GitDocker(推荐方式,避免本地 Python 环境冲突)。

步骤 1.1:获取重打包工具
社区维护了一个专门用于此场景的工具库:

git clone https://github.com/junjiem/dify-plugin-repackaging.git
cd dify-plugin-repackaging

(注:如果无法访问 GitHub,可在有网机器下载该仓库的 zip 包传入)

步骤 1.2:下载原始插件包

  1. 登录有网环境的 Dify 市场,或者直接从 GitHub Release 下载您需要的插件源码包/原始 .difypkg 文件。
    • 假设下载的文件名为 my-plugin-1.0.0.difypkg

步骤 1.3:执行重打包(关键步骤)
该工具会自动分析插件的 requirements.txtpackage.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:上传安装

  1. 登录离线环境的 Dify 控制台。
  2. 进入 插件 (Plugins)本地上传 (Local Upload)
  3. 选择刚才传输进来的 _offline.difypkg 文件进行安装。
  4. 结果:此时插件守护进程检测到包内已有依赖,将跳过 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 镜像(企业级长期方案)

如果公司插件数量巨大,每次重打包比较繁琐,可以考虑更彻底的架构改造:

  1. 搭建私有源:在离线内网搭建私有 PyPI (如 pypiserver) 和 NPM (如 Verdaccio) 服务。

  2. 预同步依赖:在有网机器上使用 pip download -r requirements.txtnpm pack 将所有可能用到的依赖下载到本地,上传至私有源。

  3. 修改 Dify 配置
    在离线环境的 docker-compose.yaml 中,为 plugin_daemon 服务注入环境变量,指定内部镜像源:

    services:
      plugin_daemon:
        environment:
          - PIP_INDEX_URL=http://<内网私服IP>:8080/simple
          - NPM_REGISTRY_URL=http://<内网私服IP>:4873
    

    注意:这需要您预先知道所有插件的依赖列表并同步到私服,维护成本较高,但一劳永逸。

常见问题排查 (Troubleshooting)

  1. 报错 Connection timed outNetwork unreachable

    • 确认您安装的是重打包后.difypkg 文件,而不是直接从市场导出的原始文件。
    • 检查 docker logs -f dify-plugin-daemon-1 (容器名可能不同),确认是否还在尝试访问 pypi.org。如果是,说明包内未包含依赖。
  2. 架构不匹配 (Wheel 文件错误)

    • dify-plugin-repackaging 默认会根据当前构建机的架构下载依赖。
    • 重要:请确保有网构建机器的操作系统和 CPU 架构(如 Linux x86_64)与离线生产环境完全一致。
    • 如果生产环境是 ARM (如鲲鹏、Mac M系列),必须在相同架构的机器上运行重打包脚本,或者使用 Docker 指定架构运行(例如在 x86 机器上用 docker run --platform linux/arm64 ... 模拟,但较复杂,建议找一台同架构的跳板机)。
  3. 权限问题

    • 确保离线环境下的 plugin_daemon 容器有权限读取挂载的插件目录。

总结

  • 现状:直接导出导入行不通,因为缺依赖。
  • 解决:必须使用 dify-plugin-repackaging 工具在有网环境进行“二次打包”,将依赖植入包内。
  • 升级策略:将此工具固化为公司内部的一个“插件构建脚本”,每次有新插件或升级时,先在构建机跑一遍脚本,产出离线包,再分发。

这是目前社区(包括 CSDN、掘金等技术博客中多位实施专家)验证过的最稳定方案。

1 个赞