
如果你所在的内网环境完全访问不了公网又要搭一套 Dify 这样的 LLM 应用开发平台最大的拦路虎往往不是平台本身有多复杂而是镜像拉不下来、插件装不上。这个问题我前前后后踩过两轮坑第一轮只导出了容器没导出镜像到了现场傻眼第二轮镜像带齐了又没考虑插件市场的离线访问结果模型插件全部装不了只能推倒重来。这篇文章把两次全量安装的记录整理成一套可以照抄的流程从镜像导出、Docker Compose 启动到插件包离线上传一步一步拆开讲清楚适合准备在内网环境做 Dify 本地部署的运维、开发同学参考。1. 离线安装的整体思路把“拉取”变成“搬移”1.1 为什么 Dify 离线安装不是解压即用很多初次接触 Dify 的人会以为拿到一份 release 压缩包解压后在 docker 目录下执行docker compose up -d就能跑起来。这个想法在公网环境下确实成立因为 Compose 文件里声明的镜像会实时从镜像仓库拉取。可一旦换成离线环境连 registry 都访问不了docker pull会一直卡在超时或者连接重置整个系统直接起不来。Dify 社区版的默认形态不是单体二进制而是一组互相协作的容器服务。用 docker compose 部署时至少涉及 API、Worker、Web、Nginx、PostgreSQL、Redis、Sandbox、Plugin Daemon 等服务有些版本还带向量数据库 Weaviate。这些镜像加起来十几个每一个都需要从远端仓库拉取。离线环境下要做的核心事情就是提前把这十几个镜像“搬”到目标机器上再在本地完成导入和启动。理解了这一点就不会把离线部署当成解压软件包而是当成一次资源迁移任务。1.2 四个必须前置收集的依赖块我后来把离线安装拆成了四个独立资源块分别处理之后流程清晰了很多。源码与配置包Dify release 提供的源码压缩包里面包含 docker 目录、docker-compose.yaml、.env.example 等关键文件。这个包在 GitLab/GitHub release 页面下载即可全部是静态文件。Docker 镜像包Compose 文件里声明的全部镜像通过docker save导出为 tar 归档。这部分体积最大通常几个 GB 到十几个 GB 不等需要提前规划好传输方式。插件包Dify 的插件市场在线安装功能在离线环境下不可用需要提前在有网机器上下载.difypkg格式的插件包再拷贝进内网通过界面上传安装。基础运行时目标机器上的 Docker Engine 和 Docker Compose 插件。离线机器如果没装需要提前下载二进制或安装包一并带进去。采坑提示镜像导出时别只看容器本身还要把 docker-compose.yaml 中使用到的镜像全部导出包括 PostgreSQL、Redis、Weaviate 这类基础设施镜像。第一次部署时我只导了 dify 官方那四个镜像到了现场容器之间互相找不到只能重新传输。1.3 部署方式选型Compose 是离线场景的默认解Dify 官方部署方式大致有 Docker Compose、源码启动和 Kubernetes 三种。离线环境下Docker Compose 是最稳的选择原因很直接源码启动需要安装 Python、Node.js还要处理 pip 和 npm 的离线依赖复杂度成倍增加Kubernetes 本身需要加载一堆 kube-system 和 ingress 镜像离线部署工作量更大小团队完全没必要。Docker Compose 把十来个服务的编排逻辑写在一个 yaml 文件里依赖关系清晰日志查看也方便最适合单人或者小团队在离线网络里维护。2. 离线部署前的资源准备与镜像搬运2.1 版本确定与配套下载离线环境安装最怕版本错配。Dify 的镜像 tag、源码版本和插件包版本必须严格对应。我的习惯是先去 GitHub release 页面选定一个明确的版本号例如 1.17.1 或当前最新稳定版然后做三件事下载对应版本的源码压缩包、在有网机器上克隆一份与 release 一致的镜像列表、下载与平台版本兼容的插件包。注意源码包要完整解压后检查 docker 目录下的 docker-compose.yaml确认里面写的镜像 tag 与 release 说明一致避免出现“源码是 1.16镜像却是 1.15”的尴尬。下载源码包后在 docker 目录下可以看到一个.env.example文件。这个文件是后面所有环境配置的起点。需要特别留意的是.env.example不能直接当.env用必须复制一份再修改因为里面有大量需要管理员手动设置的敏感字段。2.2 在有网机器上拉取并导出全部镜像这是整个离线安装里最关键的一步。执行前先进入源码中的 docker 目录用docker compose config查看最终生效的镜像列表确保你清楚知道要导出哪些镜像。cd dify-main/docker docker compose config --images这条命令会列出 Compose 文件解析后真正需要的镜像建议手动过一遍确认没有遗漏。随后逐条拉取docker compose pulldocker compose pull会按 Compose 文件定义拉取所有镜像。如果网络状况一般建议给 Docker 配置 registry mirror把 Docker Hub 请求分流到国内镜像加速地址能显著减少超时概率。全部拉取完成后用docker images查看镜像列表再统一导出docker save -o dify-all.tar \ langgenius/dify-api:1.17.1 \ langgenius/dify-worker:1.17.1 \ langgenius/dify-web:1.17.1 \ langgenius/dify-nginx:1.17.1 \ langgenius/dify-sandbox:0.2.10 \ langgenius/dify-plugin-daemon:0.0.39 \ postgres:15-alpine \ redis:6-alpine \ weaviate:1.19.0注意具体 tag 以你自己的版本为准。保存后建议用gzip压缩一遍便于传输。我遇到过一次 U 盘拷镜像时文件损坏的情况所以现在传大文件前都会先算一遍 SHA256到现场再校验一次这个习惯帮我躲过不少坑。2.3 离线机器导入镜像与初始化环境到离线机器后第一步先确认 Docker 是否可用以及docker compose是不是独立的 v2 版本docker version docker compose version如果 compose 命令不存在需要提前在安装包或二进制包里带过来。把镜像 tar 拷贝到目标机器后直接导入docker load -i dify-all.tar导入完成后执行docker images看到镜像列表就说明资源搬移成功了。接下来创建环境变量文件cd dify-main/docker cp .env.example .env然后生成安全密钥并写入配置openssl rand -base64 42把生成结果更新到.env里的SECRET_KEY字段。同时建议修改POSTGRES_PASSWORD避免使用默认密码。SECRET_KEY是 Dify 用来加密会话和敏感数据的关键凭据生产环境千万不能用固定值。最后启动服务docker compose up -d docker compose ps首次启动时 API 容器需要做数据库迁移可能要等一两分钟。等所有容器状态变为running大部分 healthy后访问http://localhost就能看到 Dify 初始化页面先设置管理员邮箱和密码然后登录进入控制台。3. Dify 插件系统的离线安装实操3.1 插件机制与离线场景的冲突Dify 进入 1.x 时代后模型 Provider、外部工具、Agent 策略都以插件形式提供。公网环境下用户直接在插件市场里搜索、一键安装即可。但在离线环境里插件市场地址完全不可达界面会一直转圈或者直接报网络错误。这就是标题里“离线安装插件”最核心的痛点。插件包的载体是.difypkg文件本质上是一个带描述文件的资源包里面会声明插件名称、版本、作者、运行的 Python/Node 入口以及依赖的 Dify 平台版本范围。离线安装插件本质上就是把这个.difypkg文件提前获取到本地再通过 Dify 后台的上传通道安装进平台。3.2 提前下载插件包的两种方式离线环境要拿到.difypkg只能在有网的机器上想办法。官方插件市场下载在有网环境登录 Dify 的插件市场页面浏览需要的插件比如 OpenAI 模型 Provider、通义千问 Provider、SerpAPI 工具等找到插件详情页的下载入口获取.difypkg。有些市场界面提供“Download Package”按钮如果找不到也可以从插件的 GitHub 仓库 release 页面找编译好的包。直接构建对应版本如果插件没有官方 release 包只能拿源码在有网环境执行构建命令生成.difypkg。这种方式要求本地具备 docker 和插件 SDK构建步骤相对繁琐但对特定内网研发团队来说可以按需定制反而更灵活。下载时要注意插件包版本号例如模型类插件会有针对 Dify 版本兼容范围的声明。一个 1.2 版本的插件包硬塞给 1.17 平台大概率安装失败或者装上后运行报错。3.3 界面上传安装 .difypkg把.difypkg文件拷贝到离线目标机器后打开 Dify 控制台。左侧菜单找到“插件”入口进入后点击“安装插件”选择“通过本地文件安装”然后选中.difypkg文件上传。上传成功后系统会解析插件包信息展示插件的名称、版本和依赖情况。如果提示安装成功插件会出现在已安装列表里。此时还需要进入对应插件的配置页面填写模型 API Key 或工具凭证才能真正使用。特别提醒离线环境里如果插件需要调用外部 API那么网络策略本身要允许访问对应模型服务如果模型服务也在内网则需要把插件配置里的 Endpoint 指向内网模型网关地址。这一点很多同学会忽略每次都要排查很久。3.4 本地插件与远程插件的选择Dify 插件有两种运行形态本地进程插件和远程插件。离线环境里强烈建议全部使用本地插件方式。远程插件要求 Docker 容器能够访问插件运行服务地址离线环境下往往不具备条件。本地插件由平台自带的 Plugin Daemon 进程直接拉起不依赖外部网络可靠性最高。需要确认的是镜像导出阶段一定不能漏掉langgenius/dify-plugin-daemon镜像。如果 Daemon 容器没有正常启动即使插件包上传成功安装时也会一直卡在“插件初始化中”日志里会出现连不上 Daemon 的错误。遇到这种情况先去容器管理页面检查 plugin_daemon 容器状态再考虑插件包本身的问题。4. 常见问题与排查技巧实录4.1 docker compose pull 一直失败或超时离线部署准备阶段最经典的问题就是拉镜像失败。公网环境拉取 Dify 镜像经常遇到网络超时、连接重置原因就是 Docker Hub 访问不稳定。解决思路有两个一个是配置镜像加速源修改 Docker daemon 配置后重启再执行docker compose pull另一个是分阶段拉取不要一次性拉十几个镜像改成一条一条拉把已经成功拉取的镜像先docker save保存避免失败后全部重来。导入端如果docker load报错大概率是 tar 文件不完整重新传输即可。4.2 Web 页面打不开或显示 502镜像和源码都就绪、服务也启动了但浏览器访问http://localhost时打不开页面。这种情况先看 Nginx 容器是否正常执行docker compose logs nginx查看日志。常见原因是宿主机 80 端口被其他服务占用导致 docker-compose.yaml 里的端口映射冲突。修改方法是在 docker-compose.yaml 里把80:80改成其他宿主机端口比如8080:80然后重新执行docker compose up -d。如果页面能打开但接口一直 502通常是 API 容器还在初始化等 1-2 分钟再刷新。Windows Docker Desktop 环境下还要确认防火墙是否放行了 Docker 的端口映射。4.3 API 容器持续重启docker compose ps显示 api 容器一直 restarting。先看日志docker compose logs api最常见原因有三个.env文件里 SECRET_KEY 未设置或格式不对PostgreSQL 数据库密码和配置不一致数据库迁移失败。逐个排查时重点检查.env里 POSTGRES_PASSWORD 与docker-compose.yaml中 POSTGRES 服务环境变量的对应关系。另外PostgreSQL 数据卷如果从上一版本继承也可能因为 schema 版本问题导致 API 迁移失败这种情况需要确认源码版本和数据卷版本是否匹配。4.4 插件安装失败或无法启用插件离线安装失败的排查思路按顺序走先看插件包是否与平台版本兼容再检查 plugin_daemon 容器是否健康最后看日志。docker compose logs plugin_daemon如果日志里出现“plugin not found”或“unsupported version”基本可以确定是插件包版本不对。如果是“sandbox create failed”一类的错误需要检查 Docker 版本是否满足 Seccomp 要求。另外部分插件第一次启用时要拉取模型列表或者下载内置模型配置离线环境下这步会卡住需要在插件配置里手动指定模型服务地址或者选择“离线模式”的 Provider 插件。4.5 数据备份与后续升级离线环境一旦正常运行最怕出问题后无法快速恢复。建议至少每周做一次 PostgreSQL 数据卷的 dump 备份docker compose exec postgres pg_dump -U postgres dify dify_backup.sql升级到新版本同样走“资源前置收集”流程下载新版源码包、在有网机器拉取新版本镜像并导出、离线导入后执行docker compose down docker compose up -d。不要直接在旧数据卷上跑新版本而不做备份我见过数据库迁移失败导致整个库不可用的情况血的教训。写在最后的小体会两轮 Dify 离线安装做完我最直观的感受是这个事真正拼的不是 Linux 命令熟练度而是部署前的资源盘点能力。镜像导出、插件包下载、版本匹配、传输校验这些准备工作做得越细现场启动就越顺。建议你建一个简单的“离线资源收集清单”文本文件把需要下载的镜像列表、插件包名称、版本号、SHA256 校验值、目标机路径全部列出来每次部署都照着清单走基本不会漏东西。如果你是在 Windows 宿主机上用 Docker Desktop 做离线部署镜像导出导入的思路和 Linux 完全一致只是传输时要注意 Docker Desktop 默认的 WSL 后端对文件路径比较敏感建议把 tar 包放在普通用户目录下避免权限问题。最后再分享一个小技巧离线机器上如果同时内网 DNS 解析有要求记得把.env里的服务访问地址写成内网 IP 或域名避免前端页面调接口时默认走 localhost 导致部分功能不可用。