Dify离线部署全攻略:从镜像打包到内网环境完整跑通 📅 发布时间:2026/9/17 5:32:44 👁 浏览次数: 做离线部署这件事最初是因为一个客户现场需要在内网环境部署一套基于大模型的文档处理平台网络完全隔离。我一开始也以为只是把Dify的镜像备份过去再启动就行真正动手才发现插件、模型配置、向量数据库这些环节在离线环境里全都会变成新的坑。这篇文章把我从镜像打包到无网环境部署完整跑通的路径记录下来包括Windows环境下的操作细节希望能帮你少走几趟弯路。1. 离线部署前必须想明白的四件事1.1 离线环境缺的不是Dify代码是整个运行时生态Dify这种平台类应用表面上看是跑在Docker容器里的一套服务但它的依赖面比你想象的宽得多。除了API后端、Web前端这两个核心容器它还依赖PostgreSQL、Redis、向量数据库默认是Weaviate也支持Qdrant等、Sandbox沙箱、SSRF代理、插件守护进程、插件Nginx入口这些组件。任何一个镜像缺失整个平台都起不来或者功能残缺。在有网环境下docker compose up -d会自动从Docker Hub拉取缺失的镜像你几乎感知不到这些依赖的存在。但在离线环境里一切都要提前打包带走。这还没完Dify 1.x版本的插件机制是独立的插件市场、插件包下载这些操作在无网环境下同样全部失效所以插件部署也是离线方案里必须单独处理的一环。我建议你动手之前先梳理清楚一件事离线部署的本质是把运行时依赖完整搬到内网而不是把应用代码搬过去。镜像、插件包、环境变量配置、模型Endpoint配置这些都要纳入打包清单。1.2 版本锁定为什么不能随便拿一个最新版很多人在离线部署时习惯直接git clone最新代码或者从Release页面下载最新的zip包然后在打包镜像。这个思路在有网环境没问题但在离线环境下会埋一个隐患Dify的API服务和插件守护进程之间存在版本兼容关系如果plugin-daemon版本落后于API版本太多会出现API容器反复报错、插件列表加载不出来的问题。我这次用的是1.17.1版本。Dify官方在GitHub上每个版本对应一个tag下载源码后进入docker目录里面的docker-compose.yaml和.env.example已经把当前版本对应的所有镜像tag写好。你只需要严格按照这个版本文件去拉取镜像不要自己去Docker Hub挑看起来最新的tag。版本锁定的另一个好处是docker-compose.yaml里各服务的镜像版本之间是经过官方测试的组合。比如1.17.1对应的plugin-daemon版本、sandbox版本、nginx版本都是固定的你混搭一个别的版本可能表面看不出问题但某个功能模块会随机抽风。1.3 Windows这条路线上容易被人忽视的坑很多人默认离线部署是Linux服务器的事实际上Windows环境不管是本地开发机还是Windows Server也有真实需求。Windows上用Docker部署Dify有几个特别容易踩的地方第一Docker Desktop的WSL 2后端。如果电脑配置一般建议手动限制WSL的内存和CPU占用不然后台跑着PostgreSQL、Weaviate这些容器风扇会狂转系统响应也会变慢。可以在用户目录下的.wslconfig里设置memory6GB或者8GB看机器内存而定。第二文件挂载路径问题。Dify的.env文件里配置了DIFY_PORT、NGINX_PORT这些端口参数Windows下要注意端口不被占用。另外docker-compose里如果有本地卷挂载Windows下的路径转换偶尔会出幺蛾子尽量使用相对路径让compose文件自动处理。第三Windows命令行执行docker命令时的编码问题。某些Windows终端环境下中文字符会在日志里显示成乱码这不是部署失败只是编码显示问题不影响功能。1.4 整体打包与部署的流程设计离线部署的流程可以抽象成五步在一台有网环境的机器上下载对应版本的Dify源码整理docker-compose配置。使用Docker拉取所有依赖镜像打包导出为tar压缩包。在联网环境下准备好需要的插件包.difypkg文件。把源码目录、镜像包、插件包一起拷贝到离线机器上。在离线上导入镜像、配置.env、启动服务、安装插件、配置模型。听起来不复杂但每一步里都有细节坑。我下面按顺序拆开讲重点说实际操作中容易翻车的地方。2. 有网环境下的镜像打包实战2.1 从GitHub获取Dify源码的正确姿势网上很多教程让直接git cloneDify仓库但如果你只需要某个特定版本用--branch参数指定tag更干净git clone --branch 1.17.1 https://github.com/langgenius/dify.git如果网络状况不理想也可以在GitHub Release页面直接下载对应版本的Source code压缩包。源码下载完成后进入dify/docker目录这个目录是部署的核心。cd dify/docker在这个目录下你会看到docker-compose.yaml、.env.example、docker-compose.middleware.yaml等文件。.env.example是环境变量模板后面部署时要复制一份改成.env再改参数。2.2 精确收集镜像清单并拉取镜像docker-compose.yaml里每一个服务节点下都有image:字段这些就是需要打包的所有镜像。我建议用命令把所有镜像名提取出来避免人工遗漏grep -E ^\simage: docker-compose.yaml | awk {print $2} | sort -u我整理了一下Dify 1.17.1默认部署方案下典型的镜像清单大致如下服务镜像名APIlanggenius/dify-api:1.17.1Weblanggenius/dify-web:1.17.1Plugin Daemonlanggenius/dify-plugin-daemon:0.2.xSandboxlanggenius/dify-sandbox:0.2.xSSRF Proxylanggenius/dify-ssrf-proxy:0.0.3Plugin Nginxlanggenius/dify-plugin-nginx:1.0.0Nginxnginx:1.27-alpinePostgreSQLpostgres:15-alpineRedisredis:6-alpineWeaviateweaviate:1.19.0注意具体版本要以你下载的源码里docker-compose.yaml为准不要直接照抄我这里的tag数字。收集好清单后直接执行docker compose pull这个命令会按compose文件里的定义把用到的所有镜像拉取到本地。这里有个我在Windows下遇到的典型报错dify拉取镜像失败。这个报错在有网环境都经常出现原因多半是Docker Desktop的DNS解析问题或镜像源不稳定。我当时的处理办法是检查Docker Desktop的Settings - Docker Engine把registry-mirrors配置成可用的镜像源再docker compose pull重试。另外确认一下系统代理设置Docker Desktop在Windows下会读取系统代理如果代理配置有问题镜像拉取也会中断。2.3 批量导出镜像到tar包镜像拉齐之后用docker save把所有镜像打包成一个tar文件。具体命令可以这样写docker save -o dify-images.tar \ langgenius/dify-api:1.17.1 \ langgenius/dify-web:1.17.1 \ langgenius/dify-plugin-daemon:0.2.x \ langgenius/dify-sandbox:0.2.x \ langgenius/dify-ssrf-proxy:0.0.3 \ langgenius/dify-plugin-nginx:1.0.0 \ nginx:1.27-alpine \ postgres:15-alpine \ redis:6-alpine \ weaviate:1.19.0如果你不想手敲也可以用一条命令把所有本地打包的镜像全导出来docker save -o dify-images-all.tar $(docker images --format {{.Repository}}:{{.Tag}} | grep -E langgenius|nginx|postgres|redis|weaviate)这里我强烈建议导出后用gzip压缩一下因为Dify全量镜像打包出来一般有3~6GB压缩完能明显减小体积拷贝时省时间docker save 镜像列表 | gzip dify-images.tar.gz导入时用docker load -i dify-images.tar.gzdocker load支持gzip压缩包格式不需要先解压。2.4 插件相关的镜像和文件也要一起带走Dify 1.x版本架构里插件不是一个可选功能而是核心能力Agent、模型接入、工具调用全依赖它。插件由plugin-daemon服务管理但插件本身是运行时从市场下载的不打包的话离线环境里插件市场页面会一直加载失败。所以有网环境阶段要做两件事第一确认plugin-daemon和plugin-nginx这两个容器镜像已经包含在镜像清单里。这两个镜像负责插件的调度和网络入口缺了它们后台插件管理界面根本打不开。第二去Dify的插件市场把需要的插件包手动下载下来。插件市场地址在Dify后台的插件页面选择你需要的插件后通常能在详细页面找到下载.difypkg文件的入口。如果页面不方便下载可以去插件对应的GitHub Release页面找.difypkg的附件。我当时提前准备的是OpenAI兼容接口插件和一些常用的工具类插件.difypkg文件下载后单独放到一个目录里后面离线安装时直接上传就行。3. 离线环境的部署与启动3.1 传输前的文件整理从有网机器往离线机器拷贝之前最好把文件整理成清晰的目录结构避免到了现场手忙脚乱├── dify-source/ # 源码压缩包或解压后的目录 │ └── docker/ │ ├── docker-compose.yaml │ ├── .env.example │ └── ... ├── dify-images.tar.gz # 镜像包 └── plugins/ # 提前下载的 .difypkg 插件包源码目录其实可以只保留docker相关的部分其他文档、测试代码带过去也没意义但为了保持完整性和方便后续排查我一般整包拷过去。传输介质方面拷贝大文件优先用移动固态硬盘U盘也行但传输速度慢拷完校验一下文件完整性比如通过SHA256哈希值一致性来确认没有损坏见下方命令Windows下用certutil -hashfile 文件名 SHA256Linux下用sha256sum。3.2 Docker Load导入镜像离线机器上先确认Docker环境正常docker version docker info然后导入镜像包docker load -i dify-images.tar.gz如果镜像包较大导入过程会持续几分钟甚至十几分钟。导入完成后务必检查镜像列表确认所有需要的镜像tag都已出现docker images | grep langgenius这个步骤一定不要省。我在实际操作中遇到过导出的tar包在解压时中断的情况docker load只导入了前面一部分镜像后面由于网络传输丢包导致镜像文件结构不完整启动容器时报错。老老实实核对完镜像列表再继续。3.3 配置.env文件的关键参数进入dify-source/docker目录cd dify-source/docker cp .env.example .env在Windows下你可以直接用记事本打开.env去编辑但我建议用VS Code这类现代编辑器改避免因编码或换行符问题导致环境变量读取异常。记事本在Windows下默认编码可能是UTF-8 with BOM某些环境变量解析器对BOM敏感会出现奇怪的问题。重点调整这几个参数SECRET_KEY生成一个随机字符串用于应用安全加密。openssl rand -base64 42如果没有openssl也可以用任意随机字符但要足够长且包含大小写字母和数字。POSTGRES_PASSWORD、REDIS_PASSWORD数据库和缓存的密码记得改掉默认值。如果你在离线环境没有特殊要求保持默认也可以但生产环境绝对要改。VECTOR_STORE默认是weaviate。如果你离线环境里需要中文知识库检索效果好一些也可以考虑qdrant但那就意味着镜像清单里还要加qdrant/qdrant并且要改docker-compose.yaml里的向量库服务定义。这个改动在设计阶段就要想好不要部署完再切换。DIFY_PORT和NGINX_PORTDify默认用80端口对外访问在Windows本机如果80被占用比如IIS、其他Web服务要改成8080之类的高位端口。PLUGIN_DAEMON_URL这个很关键。API容器需要通过这个URL访问plugin-daemon服务Windows部署时一般保持http://plugin_daemon:5002这种docker内网地址不要随便改成localhost否则容器内访问不到插件守护进程。3.4 启动服务与等待健康检查配置好.env后执行docker compose up -d第一次启动会创建容器并初始化数据库耗时比较长尤其Weaviate首次启动需要构建索引可能要到两三分钟。用以下命令观察状态docker compose ps正常情况下所有服务的STATUS列会是Up部分依赖服务的健康状态字段会显示healthy。如果某个容器反复重启先用docker compose logs 服务名查日志。启动完成后浏览器访问http://localhost:DIFY_PORT/install按流程设置管理员账号和密码。这里有个细节初次访问必须走/install初始化页面如果直接访问首页会跳转到登录页但这时还没有管理员账号容易误以为部署失败。4. 插件离线部署最容易卡住的环节4.1 搞清Dify 1.x的插件机制Dify 1.x把很多原先内置的能力拆成了插件模型接入、Agent策略、工具调用等都由插件守护进程统一管理。插件市场的入口在后端的插件页面在线环境下这个页面会从远程拉取插件市场数据离线环境下市场列表会一直转圈加载不出来。很多人在这一步误判为Dify部署失败其实平台本身是正常的只是插件市场不通。解决思路很直接提前在有网环境把插件包准备好离线后走本地安装通道。4.2 提前在联网环境准备插件包插件包的格式是.difypkg。在联网环境部署过一版Dify的话可以直接在插件市场上浏览插件找到你需要的OpenAI Compatible 系列对接OpenAI、兼容各类兼容层各类模型API插件Agent策略插件工具类插件比如bing搜索、维基百科、计算器等下载.difypkg文件后统一放到plugins目录。这里有个建议你离线后可能用到什么插件最好提前想全。因为离线机器一旦部署完再想临时增加插件只能让人重新在有网环境下载再传过来很折腾。4.3 离线安装插件包的标准流程Dify后台的插件页面在插件市场加载失败的情况下会有一个上传本地文件或通过Manifest安装的入口。操作路径大致是这样登录Dify后台进入插件页面。点击右上角安装插件按钮。选择文件上传方式。选中提前准备的.difypkg文件等待上传。上传完成后系统会解析插件包并安装安装成功后插件显示在已安装列表。这时候还需要启用插件并配置模型凭证。比如你上传了一个OpenAI兼容接口的模型插件需要到设置 - 模型供应商里把这个插件对应的模型Key配置好才能在工作流里调用。另一种方式是直接把插件包丢到plugin-daemon的数据目录下看容器是否自动加载。但说实话这种方式在Dify里并不稳定不同版本的自动扫描目录名不一样我在1.17.1测试下来还是走管理后台上传最稳妥。4.4 插件安装不生效的根因排查插件上传成功但没生效或者API接口调用时报模型不存在这种问题我遇到过几次排查方向集中在三处一是PLUGIN_DAEMON_URL是否配置正确。可以通过查看API容器日志确认docker compose logs api | grep -i plugin如果日志里有类似connect to plugin daemon failed的报错基本可以锁定是配置问题或容器启动顺序问题。二是插件包是否与Dify版本兼容。某些第三方插件包的更新频率跟不上Dify版本安装时提示插件与当前平台不兼容的话不要强行装去找插件作者的最新Release包。三是检查sandbox容器网络策略。插件的工具调用有时会走沙箱执行如果sandbox起不来工具类插件的运行会报错模型类插件则不受影响。docker compose logs sandbox如果sandbox出现权限类错误检查一下.env里的SANDBOX_API_KEY是否和docker-compose.yaml里的API_KEY一致。5. Windows下部署过程中遇到的典型故障与排查链路5.1 问题一有网机器上拉取镜像反复失败前面提到过Windows下Docker Desktop拉取镜像失败最常见的三个原因网络解析不到镜像仓库域名表现为dial tcp: lookup registry-1.docker.io on DNS:53: no such host。镜像源不稳定表现为下载到一半连接重置。代理配置异常表现为所有拉取请求超时。排查链路我建议这么走# 1. 测试能否解析仓库域名 nslookup registry-1.docker.io # 2. 测试到仓库的网络连通性 curl -I https://registry-1.docker.io/v2/ # 3. 查看Docker返回的详细报错 docker pull postgres:15-alpine确定是DNS还是代理的问题再针对性处理。Registry Mirror可以配但不同网络环境下镜像源的可用性不一样别迷信某个源多试几个。5.2 问题二API容器反复重启日志显示插件守护进程不可达巡检docker compose ps时发现api容器状态不正常频繁Restarting。查看日志docker compose logs api | tail -100日志里出现类似[PluginDaemon] failed to connect to plugin daemon的记录说明API服务在启动时尝试连接plugin-daemon失败。排查链路如下确认plugin-daemon容器本身是否正常docker compose ps里plugin_daemon状态如果不是Up先从这个容器查起。确认.env里PLUGIN_DAEMON_URL的地址。如果在Windows下误改成了http://localhost:5002API容器内的localhost指的是它自己不是宿主机必然连不上。应该保持http://plugin_daemon:5002这种docker DNS名称。确认容器间网络正常可以进入api容器做一次网络连通性测试docker compose exec api curl http://plugin_daemon:5002/health如果curl返回JSON格式的健康状态数据说明网络是通的问题大概率出在配置解析上。5.3 问题三Windows防火墙拦截容器网络这个坑比较隐蔽。在Windows上跑Docker Desktop时容器对外映射的端口比如80或8080如果在本机浏览器都访问不了但容器内访问正常几乎可以确定是Windows防火墙拦住了Docker的虚拟网卡。我的排查方式是打开Windows防火墙的高级设置在入站规则里找到Docker Desktop或者对应端口的相关规则确认是否允许。本地调试时最简单粗暴的方法是临时关闭防火墙验证如果是防火墙导致再加放行规则。还有一个容易忽略的点是Windows上的端口占用。如果.env里配置的NGINX_PORT80但本机有进程占用80端口Nginx容器会启动失败表现为一直在重启循环。查看日志能直接看到bind: address already in use之类的报错改掉端口即可。5.4 问题四Weaviate起不来知识库功能不可用Weaviate是Dify默认的向量数据库知识库的上传、检索都依赖它。离线下如果Weaviate容器起不来Dify虽然能登录后台但知识库页面创建数据集或上传文档时必然报错。我遇到的情况是宿主机内存不足Docker Desktop分配的内存不够Weaviate启动后内存溢出被系统杀掉。重启容器时一直伴随重启。这种情况下先检查宿主机可用内存和Docker配置给WSL的内存上限把内存配额调大。其次检查Weaviate容器的日志看是内存问题还是磁盘问题。docker compose logs weaviate | tail -505.5 通用排查手段三件套离线部署Dify的过程中如果遇到诡异问题我建议先做这三件事docker compose ps看所有容器的当前状态。docker compose logs --tail50 服务名看具体服务的最新日志。docker inspect 容器名看容器的环境变量和挂载配置是否符合预期。大部分问题都能在这三件套里找到线索尤其不要一来就怀疑镜像缺失或文件损坏先确认基础状态再判断问题层次。6. 离线部署之后的收尾建议平台能访问、管理员能登录、模型插件配置好、知识库能建立这套离线部署就算真正跑通了。我个人在多次重复这个流程后的经验是不管你之前做过几次每次开始前都把镜像清单和插件清单重新对一遍。版本升级后镜像列表会有变化插件兼容性也会有调整别拿旧经验直接套新版。另外建议在离线机器上保留一份完整的部署记录包括.env的关键配置、插件的版本、模型的Endpoint配置。这批机器通常长期不联网等半年后需要扩容或升级时这份记录的价值会非常明显。如果你需要在更多节点部署后面完全可以基于这套镜像包做一个私有镜像仓库把tar导入到内网的Registry里其他机器直接从内网Registry拉取。不过那属于另一个话题了先把单机离线跑通比什么都重要。