Dify插件内网安装,解决Dify1.x插件安装总失败问题,手把手教你暴力破解:从镜像源到二进制打包全攻略

发布于:2025-04-18 ⋅ 阅读:(15) ⋅ 点赞:(0)

背景

自从dify升级到1.0以后,所有的工具和模型都改成了插件化,需要进行插件的安装。在手撕Dify1.x插件报错!从配置到网络到Pip镜像,一条龙排雷实录 已经指出了dify在线安装插件的各种问题。

首发地址

在前面的几个版本中,dify是从https://raw.githubusercontent.com 扫描获取模型插件的信息。因为网络的问题,导致好多用户感觉卡顿。不过后面升级以后,这块已经没有了。

在最开始的时候配置文件中有一个MARKETPLACE_API_URL=https://marketplace.dify.ai插件市场的配置的。这个配置允许我们自己搭建插件市场。

在dify的github仓库中,有两个项目dify-official-pluginsdify-plugins,存放的是官方和其他人发布的插件,理论上,我们都下载这两个目录,通过本地上传的方式都能安装上去。

但是插件安装的过程中收到机器、网络等原因,好多人安装插件超时,然后失败。

官方在在3月9日的提交中增加了PLUGIN_PYTHON_ENV_INIT_TIMEOUTPLUGIN_MAX_EXECUTION_TIMEOUT 来增加python环境初始化超时时间和插件最大执行超时时间来解决。

但是有的插件安装的时候依赖一些python组件,需要通过pip安装,默认pip安装都是走的pip官方的。国内安装一直存在卡顿的问题。

3月10日的代码提交中,官方支持自定义pip安装镜像地址。解决了插件依赖网络的问题。

官方基本上一步一步的在解决国内安装插件的问题。

本地安装

我们打开https://marketplace.dify.ai/ 插件市场,根据分类,找到自己想要安装的插件。

ps:在官方的两个仓库中查找,也可以的,但是没有分类。

比如我们拿ollama举例,在插件市场找到ollama,然后打开

  • 1标识的是插件开发商以及插件名称。在官方库里能找到对应的源码。
  • 点击2箭头指向的下载按钮。下载插件

    下载以后是一个difypkg文件。

    在自己的dify应用中,点击插件,打开安装插件的本地插件,上传。

    选择刚下载的插件。

    选择完以后,就会提示安装或更新。

官方有个提示可信源安装插件,这块需注意下,不要随意安装别人分享的插件,上传到插件市场的插件,官方应该都会过一遍,要不然也不能叫可信源。


我们在官方的查看中可以查看,简单的一个ollama都需要安装依赖环境。如果一般内网都有自己的镜像源,替换下自己的镜像源,在dify的配置文件中改成自己的镜像源即可。

无网安装

有些用户说内网不能联网,没法安装,但是我想说的是,一般内网隔离,一般都会有一些自己的镜像源。如果内网环境不提供镜像源,那都是在耍流氓。

网上也有一个解决办法。在github上,有个哥们分享了一个项目https://github.com/junjiem/dify-plugin-repackaging 这个可以将dify的插件以及相关的依赖打包成离线的插件包。我先用deepseek-v3帮我画一个流程图

无参数
有参数
market
参数完整
参数不完整
github
参数完整
参数不完整
local
参数完整
参数不完整
开始
检查参数
显示帮助信息
命令类型
检查market参数
从Dify市场下载插件
检查github参数
从GitHub下载插件
检查local参数
使用本地插件包
调用Repackage函数
解压插件包
创建wheels目录
下载依赖到wheels
修改requirements.txt
更新.difyignore
执行打包工具
生成离线插件包
结束

从流程图上可以看到这个脚本,支持从dify marketgithublocal这3个地方打包。

  • 主要是将插件依赖的包,下载到wheels包中
  • 然后打包

这个脚本在centos中是可以直接运行的。可以看下面的代码。其他的环境需要改造下。

install_unzip(){

  rpms=(`rpm -q unzip`)

  if [ ${#rpms[@]} -ne 1 ]; then

    echo "Installing unzip ..."

    yum -y install unzip

    if [ $? -ne 0 ]; then

      echo "Install unzip failed."

      exit 1

    fi

  fi

}

win11环境

我以win11环境为示例演示下。

下载项目
git clone https://github.com/junjiem/dify-plugin-repackaging.git
脚本生成

首先我让deepseek-v3模型帮我生成一个兼容win11的脚本。

<#
.SYNOPSIS
    Dify 插件下载和重新打包工具(Windows PowerShell 版本)
.DESCRIPTION
    提供三种方式获取和重新打包 Dify 插件:
    1. 从 Dify 官方市场下载
    2. 从 GitHub 仓库下载
    3. 使用本地已有的插件包
.NOTES
    作者: yxkong
    版本: 1.0
#>

# 全局变量
$GITHUB_API_URL = "https://github.com"
$MARKETPLACE_API_URL = "https://marketplace.dify.ai"
$PIP_MIRROR_URL = "https://mirrors.aliyun.com/pypi/simple"

# 获取当前脚本所在目录
$CURR_DIR = $PSScriptRoot
if (-not $CURR_DIR) {
    $CURR_DIR = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
}

# 主函数
function Main {
    param (
        [string]$Command,
        [string[]]$Arguments
    )

    switch ($Command.ToLower()) {
        "market" {
            Market @Arguments
        }
        "github" {
            GitHub @Arguments
        }
        "local" {
            Local @Arguments
        }
        default {
            ShowHelp
            exit 1
        }
    }
}

# 显示帮助信息
function ShowHelp {
    Write-Host @"
用法: .\$($MyInvocation.MyCommand.Name) {market|github|local} [参数]

命令:
  market   从 Dify 官方市场下载插件
    示例: .\$($MyInvocation.MyCommand.Name) market junjiem mcp_sse 0.0.1

  github   从 GitHub 仓库下载插件
    示例: .\$($MyInvocation.MyCommand.Name) github junjiem/dify-plugin-tools-dbquery v0.0.2 db_query.difypkg

  local    使用本地已有的插件包
    示例: .\$($MyInvocation.MyCommand.Name) local ./db_query.difypkg
"@
}

# 从 Dify 市场下载
function Market {
    param (
        [string]$pluginAuthor,
        [string]$pluginName,
        [string]$pluginVersion
    )

    if (-not $pluginAuthor -or -not $pluginName -or -not $pluginVersion) {
        Write-Host "参数错误!用法: .\$($MyInvocation.MyCommand.Name) market [插件作者] [插件名称] [插件版本]"
        exit 1
    }

    Write-Host "从 Dify 市场下载插件..."
    $pluginPackagePath = Join-Path $CURR_DIR "${pluginAuthor}-${pluginName}_${pluginVersion}.difypkg"
    $pluginDownloadUrl = "${MARKETPLACE_API_URL}/api/v1/plugins/${pluginAuthor}/${pluginName}/${pluginVersion}/download"

    try {
        Write-Host "正在下载 ${pluginDownloadUrl} ..."
        Invoke-WebRequest -Uri $pluginDownloadUrl -OutFile $pluginPackagePath -UseBasicParsing
        Write-Host "下载成功。"
        Repackage $pluginPackagePath
    }
    catch {
        Write-Host "下载失败: $_"
        exit 1
    }
}

# 从 GitHub 下载
function GitHub {
    param (
        [string]$repo,
        [string]$releaseTitle,
        [string]$assetsName
    )

    if (-not $repo -or -not $releaseTitle -or -not $assetsName) {
        Write-Host "参数错误!用法: .\$($MyInvocation.MyCommand.Name) github [GitHub 仓库] [发布标题] [资源文件名]"
        exit 1
    }

    Write-Host "从 GitHub 下载插件..."
    
    if (-not $repo.StartsWith($GITHUB_API_URL)) {
        $repo = "${GITHUB_API_URL}/${repo}"
    }

    $pluginName = $assetsName -replace '\.difypkg$', ''
    $pluginPackagePath = Join-Path $CURR_DIR "${pluginName}-${releaseTitle}.difypkg"
    $pluginDownloadUrl = "${repo}/releases/download/${releaseTitle}/${assetsName}"

    try {
        Write-Host "正在下载 ${pluginDownloadUrl} ..."
        Invoke-WebRequest -Uri $pluginDownloadUrl -OutFile $pluginPackagePath -UseBasicParsing
        Write-Host "下载成功。"
        Repackage $pluginPackagePath
    }
    catch {
        Write-Host "下载失败: $_"
        exit 1
    }
}

# 使用本地插件包
function Local {
    param (
        [string]$packagePath
    )

    if (-not $packagePath) {
        Write-Host "参数错误!用法: .\$($MyInvocation.MyCommand.Name) local [插件包路径]"
        exit 1
    }

    $fullPath = Resolve-Path $packagePath -ErrorAction SilentlyContinue
    if (-not $fullPath) {
        Write-Host "文件不存在: $packagePath"
        exit 1
    }

    Repackage $fullPath.Path
}

# 重新打包插件
function Repackage {
    param (
        [string]$packagePath
    )

    $packageNameWithExt = [System.IO.Path]::GetFileName($packagePath)
    $packageName = [System.IO.Path]::GetFileNameWithoutExtension($packagePath)
    $extractDir = Join-Path $CURR_DIR $packageName

    Write-Host "解压中..."
    try {
        # 确保解压目录存在
        if (Test-Path $extractDir) {
            Remove-Item $extractDir -Recurse -Force
        }
        New-Item -ItemType Directory -Path $extractDir | Out-Null

        # 使用内置解压功能
        Expand-Archive -Path $packagePath -DestinationPath $extractDir -Force
        Write-Host "解压成功。"
    }
    catch {
        Write-Host "解压失败: $_"
        exit 1
    }

    Write-Host "重新打包中..."
    try {
        # 进入解压目录
        Push-Location $extractDir

        # 创建 wheels 目录
        $wheelsDir = Join-Path $extractDir "wheels"
        if (-not (Test-Path $wheelsDir)) {
            New-Item -ItemType Directory -Path $wheelsDir | Out-Null
        }

        # 下载依赖
        if (Test-Path "requirements.txt") {
            Write-Host "正在下载依赖..."
            python -m pip download -r requirements.txt -d $wheelsDir --index-url $PIP_MIRROR_URL
            
            # 修改 requirements.txt
            $requirementsContent = "--no-index --find-links=./wheels/`r`n" + (Get-Content "requirements.txt" -Raw)
            $requirementsContent | Set-Content "requirements.txt"
        }

        # 更新 .difyignore 文件
        if (Test-Path ".difyignore") {
            $difyIgnoreContent = Get-Content ".difyignore" | Where-Object { $_ -notmatch "^wheels/" }
            $difyIgnoreContent | Set-Content ".difyignore"
        }

        # 返回原始目录
        Pop-Location

        # 检查打包工具是否存在
        $packageTool = Join-Path $CURR_DIR "dify-plugin-windows-amd64-5g.exe"
        if (-not (Test-Path $packageTool)) {
            Write-Host "错误: 找不到打包工具 $packageTool"
            exit 1
        }

        # 执行打包
        $outputPackage = Join-Path $CURR_DIR "${packageName}-offline.difypkg"
        & $packageTool plugin package $extractDir -o $outputPackage

        Write-Host "重新打包成功。输出文件: $outputPackage"
    }
    catch {
        Write-Host "重新打包失败: $_"
        exit 1
    }
    finally {
        Pop-Location -ErrorAction SilentlyContinue
    }
}

# 入口点
if ($args.Count -eq 0) {
    ShowHelp
    exit 1
}

Main $args[0] $args[1..($args.Count-1)]

  1. 保存为 dify-plugin-helper.ps1 文件
  2. 在 PowerShell 中运行(可能需要先执行 Set-ExecutionPolicy RemoteSigned
  3. 其他环境类似,直接让deepseek生成对应平台的脚步即可
命令执行


我们在插件市场取这上图的3个参数。然后执行下面的命令

 #示例
 .\dify-plugin-helper.ps1 market 参数1  参数2 参数3
 # 具体命令
 .\dify-plugin-helper.ps1 market langgenius ollama 0.0.5
  • 建议直接从market下载,如果想从github或local下载,自行实验


从上面的日志中我们可以看出,在下载相关依赖。

对应的目录中也有对应的包了。

我们可以看到相关的依赖包都是对应环境的依赖包。到这一步,可以将这个包目录复制到容器中,进行手动执行了。


因为我对打包这个没研究,最后一步报错了。项目中dify-plugin-linux-amd64-5g是一个二进制文件,我先不研究这个怎么来的。我在官方仓库里搜索了下,也有这个打包脚本。都和操纵系统挂钩。

打包以后,会打包一个带有相关依赖的离线包,我们直接上传安装即可。

注意事项

需要注意的是,由于自己打的包,没有经过dify官方的审核,所以需要修改下配置。打包以后依赖的相关包比较多,附件会比较大,也需要修改下配置(ollama打包以后十几mb)。

  • 在 .env 配置文件将 FORCE_VERIFYING_SIGNATURE 改为 false ,Dify 平台将允许安装所有未在 Dify Marketplace 上架(审核)的插件。
  • 在 .env 配置文件将 PLUGIN_MAX_PACKAGE_SIZE 增大为 524288000,Dify 平台将允许安装 500M 大小以内的插件。
  • 在 .env 配置文件将 NGINX_CLIENT_MAX_BODY_SIZE 增大为 500M,Nginx客户端将允许上传 500M 大小以内的内容。

配置修改以后,不生效,需要先docker compose down然后docker compose up -d

在打包的时候,最好找一台和内网环境类似的操作系统,特别是系统架构python版本 ,有些依赖是适配到python版本的。

相关资料

deepseek相关资料
https://pan.quark.cn/s/faa9d30fc2bd
https://pan.baidu.com/s/10vnv9jJJCG-KKY8f_e-wLw?pwd=jxxv

群友分享的一些dify工作流

https://pan.baidu.com/s/1aNne8dLz6YxoKhCwJclV5g?pwd=p4xc
https://pan.quark.cn/s/243a0de062e5

系列文档:

DeepSeek本地部署相关

ollama+deepseek本地部署
局域网或断网环境下安装DeepSeek
vlllm部署deepseek基准测试

DeepSeek个人应用

不要浪费deepseek的算力了,DeepSeek提示词库指南
服务器繁忙,电脑配置太低,别急deepseek满血版来了
DeepSeek+本地知识库:真的太香了(修订版)
DeepSeek+本地知识库:真是太香了(企业方案)
deepseek一键生成小红书爆款内容,排版下载全自动!睡后收入不是梦
最轻量级的deepseek应用,支持联网和知识库
当我把公众号作为知识库塞进了智能体后
个人神级知识库DeepSeek+ima 个人学习神器

dify相关

DeepSeek+dify 本地知识库:真的太香了
Deepseek+Dify本地知识库相关问题汇总
dify的sandbox机制,安全隔离限制
DeepSeek+dify 本地知识库:高级应用Agent+工作流
DeepSeek+dify知识库,查询数据库的两种方式(api+直连)
DeepSeek+dify 工作流应用,自然语言查询数据库信息并展示
聊聊dify权限验证的三种方案及实现
dify1.0.0版本升级及新功能预览
Dify 1.1.0史诗级更新!新增"灵魂功能"元数据,实测竟藏致命Bug?手把手教你避坑
【避坑血泪史】80次调试!我用Dify爬虫搭建个人知识库全记录
手撕Dify1.x插件报错!从配置到网络到Pip镜像,一条龙排雷实录
dify1.2.0升级,全新循环节点优化,长文写作案例

ragflow相关

DeepSeek+ragflow构建企业知识库:突然觉的dify不香了(1)
DeepSeek+ragflow构建企业知识库之工作流,突然觉的dify又香了
DeepSeek+ragflow构建企业知识库:高级应用篇,越折腾越觉得ragflow好玩
RAGFlow爬虫组件使用及ragflow vs dify 组件设计对比
从8550秒到608秒!RAGFlow最新版本让知识图谱生成效率狂飙,终于不用通宵等结果了
以为发现的ragflow的宝藏接口,其实是一个天坑、Chrome/Selenium版本地狱
NLTK三重降噪内幕!RAGFlow检索强悍竟是靠这三板斧
从代码逆向RAGFlow架构:藏在18张表里的AI知识库设计哲学
解剖RAGFlow!全网最硬核源码架构解析

扣子(coze)

AI开发新选择:扣子平台功能详解与智能体拆解
AI开发新选择:扣子平台工作流基础节点介绍

模型微调相关

模型微调之基础篇:模型微调概念以及微调框架

📢【三连好运 福利拉满】📢

🌟 若本日推送有收获:
👍 点赞 → 小手一抖,bug没有
📌 在看 → 一点扩散,知识璀璨
📥 收藏 → 代码永驻,防止迷路
📤 分享 → 传递战友,功德+999
🔔 关注 → 关注5ycode,追更不迷路,干货永同步

💬 若有槽点想输出:
👉 评论区已铺好红毯,等你来战!

网站公告

今日签到

点亮在社区的每一天
去签到