
简介国内可用的 Dify 项目 Docker 镜像资源包对应 dify-main 版本专为国内网络环境下的部署做了适配配置好国内 Docker 镜像源后即可较快拉取或加载运行避免直连 Docker Hub 的限速与不稳定问题适合需要私有化部署 Dify 或进行本地二次开发的团队及个人开发者。压缩包为 zip 格式共 2000 个文件以 Python 脚本1411 个和 JSON 配置370 个为主体另含 CSS 样式、Markdown 文档、JavaScript、YAML 编排配置及 Shell 脚本等比较完整地覆盖从代码实现到容器编排的常见要素整体体积约 20.29MB目录结构清晰便于按模块检索定位相关代码。目前已有 1481 人浏览学习通过该资源可直接获得项目源码与部署辅助脚本并能从 yaml/sh 文件中理解容器启动流程对于需要快速上手的开发者尤为实用。若想在此基础上做二次开发或迁移至自有环境内置的 sh 脚本与 yaml 编排也能提供清晰的启动示范缩短从拉取镜像到跑通服务的时间作为 Dify 国产化落地或持续集成的起步模板很合适。1. 为什么要在国内服务器上装一个镜像版 Dify先避开最长的一截等待我自己第一次装 Dify 时花了两天才把整套容器从 Docker Hub 拉下来中途超时、断流、镜像层校验失败全遇上了。那时候就明白对国内部署来说Dify 本身配置并不复杂真正的阻力全在网络这一截。镜像版本做的就是把 docker pull 这一步替你完成并打包好拿到国内服务器上能直接导入省掉最折磨人的等待。这个镜像版本来自 dify-main 分支版本相对较新适合想在私有服务器上搭一套 LLM 应用平台的团队或独立开发者。如果你是做知识库问答、Agent 工作流编排这类需求又不想在环境准备上浪费两天这篇笔记能直接照着走。2. 先看懂镜像版的容器关系再动手api、worker 和它背后的三个持久化服务2.1 Dify 的主容器组里到底有什么Dify 的部署形态是一整套 docker compose 服务组。第一次打开镜像版本里的 docker-compose.yaml 时里面服务数量不少但真正承担业务逻辑的核心容器只有三个api、worker 和 web。其余大多是支撑这些主服务的数据库、缓存和向量存储。api 容器负责的是 Dify 后端接口、工作流编排、对话管理和知识库的检索逻辑调用它是整个平台的控制中心。worker 容器承担异步任务比如知识库文档的文本切分、embedding 生成、批量索引构建这些任务如果放在 api 进程里同步执行容易互相拖慢所以 Dify 单独把 worker 拆出来跑。web 容器就是前端 Nginx 服务负责你浏览器看到的控制台页面它还会把请求转发给 api。这三个核心容器之外还需要一套持久化组件配合。Postgres 存业务数据比如用户、应用配置、对话记录和知识库元数据Redis 做缓存和任务队列的中间层向量数据库负责存文档的 embedding 向量知识库问答时的语义检索全靠它。向量库默认配置的是 weaviate如果你在新版本里看到 qdrant 也出现在服务列表里别急着删先确认镜像版本默认启用哪个再决定要不要关。服务名角色说明api后端接口、工作流引擎、知识库检索调用worker异步任务文档切分、embedding 生成、索引构建web前端页面 Nginx反向代理到 apipostgres业务数据持久化redis缓存与队列weaviate / qdrant向量存储知识库问答依赖理解容器组关系之后你再去看 docker-compose.yaml 就不会被十几行服务列表吓到。排障时也方便页面打不开查 web 和 api知识库索引不走查 worker对话记录丢失查 postgres。2.2 部署前要准备好的三样东西网上很多教程一上来就让你跑 docker compose up但准备好前置条件再动手后面排障会省一半时间。第一样是 Docker 环境。镜像版本里的 compose 文件用的是新版指令建议 Docker 20.10 以上、Docker Compose v2。你可以先用命令确认环境版本服务器上执行docker --version docker compose version这里看到 compose 输出的是Docker Compose version v2.x.x就没问题。如果服务器只有docker-compose这个旧命令也能用但注意新版镜像包的 compose 文件可能用了depends_on的条件语法旧版本解析会报错我一般提前把环境升到 v2。第二样是模型 API Key。Dify 平台本身不提供模型推理能力它负责编排和调度真正的对话生成要调外部模型接口。所以你至少要先准备好一个能用的模型服务商 KeyOpenAI 兼容接口的或者国内模型厂商的都行。部署完成后第一件事就是在后台配置模型供应商这块晚点配也不影响启动但建议提前准备好省得跑通了页面却试不了对话。第三样是 IP 和端口规划。Dify 默认通过 Nginx 暴露 80 端口你在浏览器里访问的就是类似http://服务器IP的地址。要确认服务器安全组放行了这个端口如果 80 端口被其他服务占用要提前想好换哪个端口比如 8080。这个端口不是写死在容器里的而是在 .env 文件里通过参数控制后面会详细说。2.3 镜像版本包比源码安装多给了什么如果你之前参考过 Dify 官方文档会发现安装步骤其实不长拉代码、改 .env、docker compose up。那镜像版本的价值在哪首先是版本锁定。dify-main 这个镜像版本是构建时的固定产物镜像的 tag 和 digest 是确定的。源码部署有个比较头疼的问题昨天 docker compose pull 拉下来的镜像和今天拉的可能不是同一个版本因为依赖会自动解析到新的镜像 tag。生产环境里这种不确定很讨厌昨天还能跑通的流程今天重装一次就报数据库迁移失败。镜像版本把这个问题直接消掉了——你拿到的镜像是什么版本跑起来就是什么版本不存在滚动更新引入的隐性问题。其次是网络策略不同。源码部署要实时拉取多个镜像层国内服务器直连 Docker Hub 经常超时反复重试很消耗时间。镜像版本包是把所有相关镜像打成单个 tar 文件压缩在一个包里。你只需要把这一个包传到服务器上用 docker load 导入即可后面就不再依赖外部网络了。再看这个镜像包内部的文件结构主要有几样东西文件/目录作用docker-compose.yaml容器编排定义服务列表和依赖关系.env.example环境变量模板复制为 .env 后按需修改docker/volumes持久化数据目录Postgres、Redis、向量库的数据都在这里挂着镜像 tar 包包含 api、worker、web 及依赖容器的镜像docker load 导入动手之前先把这些文件过一遍尤其是 docker/volumes 这个目录后续所有备份恢复操作都围绕它做。接下来就进入实际操作。3. 从 tar 包到能访问页面离线导入、.env 配置与启动验证3.1 离线导入镜像的正确顺序镜像版本的 tar 包通常体积不小几个核心镜像加依赖容器加起来有几个 GB 是正常的。传到服务器之后第一步不是解压而是先用 docker load 把镜像导入本地镜像仓库。# 假设镜像包名为 dify-images.tar docker load -i dify-images.tar执行完会看到每个镜像的加载输出最后会显示Loaded image加上镜像名和 tag。这一步相当于在服务器本地把镜像仓库里少的那一截弥补回来后续 compose 启动时即使不联网也能找到镜像。镜像加载后确认一下是否完整docker images | grep -E langgenius|dify正常会列出 api、worker、web 以及 postgres、redis、weaviate 等镜像。如果你发现某个镜像缺失别急着进入下一步多半是 tar 包传输损坏或者被截断了。重新传一次注意用二进制模式传输不要在 Windows 下用文本模式传。这里有一个很关键的顺序问题如果服务器上已经跑过旧版 Dify建议先停掉旧容器再导入新镜像避免镜像标签被覆盖后新旧容器混用。# 如果之前部署过 Dify先进入旧目录停掉容器 # 这里以你旧项目所在目录为例 cd /opt/dify docker compose down这一步的核心目的是切断旧容器对镜像层的引用否则镜像被覆盖后旧容器还在内存里运行新启动的容器可能引用到不一致的镜像 ID。我踩过这个坑没 down 旧容器直接 load 新镜像结果 web 容器一直起不来日志报 manifest 相关错误。3.2 修改 .env 里的关键配置镜像版本包通常在 docker 目录下自带 .env.example 文件第一步先复制成 .envcp .env.example .envDify 的环境变量参数很多但真正影响你首次部署成败的并不多。我按优先级把必改参数列出来。首先是端口映射。默认情况下 Dify 的 Nginx 容器把宿主机 80 端口映射到容器内 80如果你的服务器 80 端口已经被占用需要改掉外网暴露端口# 修改 .env 中的以下参数 EXPOSE_NGINX_PORT8080 NGINX_PORT80这里要区分两个端口EXPOSE_NGINX_PORT是宿主机对外暴露的端口也就是你最终访问用的端口NGINX_PORT是容器内部的监听端口一般保持 80 不动即可。有些新手会把 NGINX_PORT 也改成 8080结果是容器内 Nginx 监听 8080但 compose 里映射关系没变反而造成端口不匹配页面一直转圈。记住只管 EXPOSE 那个参数。然后是数据库密码。默认 Postgres 密码是公开的虽然是内网服务还是建议改一下# 修改 .env 中的以下参数 POSTGRES_PASSWORD你的自定义密码这个密码会被 compose 文件引用赋值之后不要手动去改 docker 目录下 postgres 容器的环境变量容易造成密码不一致。改完密码会导致原有的 volumes 里的数据校验失败不会但如果你已经启动过一次再改密码Postgres 容器会初始化失败这一点在避坑章节说。还有一项目前国内部署场景需要留意的如果你计划接入国内模型服务商的 API建议先看 .env 里有没有模型相关的配置模板。Dify 的模型配置主要在控制台界面完成.env 里一般不写模型 API Key但有些镜像版本会把默认模型地址预设成官方地址你后续在后台填自定义 API 地址时注意覆盖。3.3 启动容器并完成第一次访问验证.env 改好后在 docker 目录下执行启动命令docker compose up -d首次启动不要立刻刷新页面容器启动需要时间。Postgres 初始化数据库结构大概需要一分钟api 容器要等数据库就绪才执行迁移web 容器要等 api 起来才能正常转发。这时候用日志观察进度docker compose ps docker compose logs -f api | tail -30docker compose ps能列出所有服务的运行状态看到 api、worker、web 都是Up状态、(healthy)字样或者至少没有Restarting说明容器层面没问题。logs是看 api 容器的实际日志如果出现Running migrations之类的输出就继续等着如果出现connection refused指向 postgres多半是 Postgres 还没初始化完再等 30 秒。容器全部起来后用 curl 验证 Nginx 端口是否通了。以改后端口的 8080 为例curl -I http://localhost:8080返回 HTTP 200 或者 302 都正常302 可能是重定向到初始化页面。如果你用的是云服务器记得还要在安全组放行对应端口否则外部访问依然失败。这个安全组放行很容易漏我经常是容器全起来了页面的打不开最后一查是安全组规则没加比较尴尬的翻车。浏览器访问http://服务器IP:8080首次进入会看到管理员账号初始化页面设置完管理员账号后进入控制台。到这里镜像版本的 Dify 已经跑起来了。提示第一次访问初始化页面时Dify 会要求设置管理员邮箱和密码这个账号用于登录后台不要和后续配置的模型 API Key 混淆。4. 部署避坑与常见问题排查四条必须写进笔记的踩坑记录4.1 现象docker pull 反复超时重试一小时后容器还是起不来原因这是最基础的网络问题目标仓库镜像层传输链路长断流后 Docker 会卡在某个层反复重试且多镜像并行下载时更容易触发校验失败。解决不要死磕docker compose pull直接用离线导入的方式。镜像版本存在的意义就是绕开这一截网络依赖。你把镜像 tar 包传到服务器后用docker load一次导入后续所有容器启动都从本地镜像仓库读取不再需要联网拉取。如果 tar 包传输中断改用压缩分包传输或者 MD5 校验包完整性后再导入。4.2 现象容器全部是 Up 状态但浏览器访问页面打不开或者打开的是空白页原因大概率是端口映射出了问题。80 端口被服务器上的其他服务占用最终请求没有落到 Dify 的 Nginx 容器上。解决先确认你访问的是不是正确端口。如果你按照默认的 80 端口访问但 .env 里的 EXPOSE_NGINX_PORT 已经被改动过那访问必然失败。修改 .env 后要重新创建容器# 修改 .env 后必须重新创建容器让新端口映射生效 docker compose up -d注意这里不能用docker compose restartrestart 只会重启容器进程不会重新应用 .env 里的端口映射变更。只有 up -d 才会检查到 .env 变化并重建受影响容器。如果确认端口没改过再排查安全组和防火墙。4.3 现象模型 Key 填了但对话测试报 connection timeout 或者 cannot connect to model provider原因Dify 发起的是从 api 容器到模型服务商接口的请求超时原因可能来自两个方向。一是 api 容器所在服务器到模型接口的网络链路本身波动二是模型服务商侧对调用来源有校验比如 API Key 绑定的地区限制或者 IP 白名单。解决先在服务器上用 curl 单独测试模型 API 地址的连通性这一步能快速定位问题是不是出在 Dify 之外# 以 OpenAI 兼容接口为例替换为你的实际模型 API 地址和 Key curl -I https://你的模型API地址/v1/models \ -H Authorization: Bearer 你的API-Key如果 curl 返回 401 或者 200说明网络通问题在 Dify 侧配置如果 curl 本身超时或者返回 403先找模型服务商确认地区和 IP 限制。Dify 侧配置模型供应商时有些服务商要求你在填 API 地址时不用带/v1后缀有些又必须带加不加以服务商文档为准。这块属于接口兼容性差异和 Dify 本身无关。4.4 现象升级镜像版本后对话记录消失工作流运行报数据库异常原因升级时直接替换了 api 镜像新的 api 启动时会对数据库执行表结构迁移迁移过程中旧数据读取异常或者迁移没跑完成导致应用数据不可见。解决升级前必须备份整个 volumes 数据目录。这是我之前升级吃过的大亏以为 docker compose down 再 up 就行结果应用数据全部丢失知识库索引重建花了半天。备份最简单的做法是直接拷贝数据目录# 在 docker 目录下执行将 volumes 整个备份走 tar -czf dify-volumes-backup-$(date %Y%m%d).tar.gz volumes恢复时把备份包解压回原目录再启动容器即可。这个习惯很值得养成Dify 的版本升级不复杂但数据回滚的后悔药全靠备份目录没备份就只能接受丢数据的现实。注意Postgres 的数据和向量库的数据都在 volumes 目录下备份时不要只备份 postgres 子目录整个 volumes 一起走才能保证对话记录和知识库索引全面恢复。5. 把镜像版 Dify 用到日常模型接入顺序、配置校验与版本冻结习惯5.1 先跑通一个模型再扩展供应商进入 Dify 控制台后第一件事是去“设置—模型供应商”页面配置模型。我的习惯是先接一个最简单的官方兼容接口用一个小模型把对话跑通然后再逐步添加国内模型服务商或者其他私有模型。为什么不直接全配好因为模型供应商配置涉及 API 地址、Key、模型名称三个要素任何一个填错都是黑匣子一样的报错。先只配置一个测试对话能返回内容就证明整个链路是通的——Dify 没问题、网络没问题、Key 没问题。后续再加新供应商时如果报错对照这个已经跑通的例子逐个参数检查就好。你如果一上来就配五六个供应商出了问题根本分不清是哪个环节错了。5.2 用 docker compose config 做修改前校验每次改动 .env尤其是改了端口、Postgres 密码这类影响容器创建的参数不要直接 up -d先跑一遍配置校验命令# 确认 .env 改动已生效 docker compose config | grep -E EXPOSE_NGINX_PORT|POSTGRES_PASSWORDdocker compose config会把 compose 文件加 .env 变量解析后的最终配置输出grep只看关键参数。这样能提前发现变量拼写错误、端口冲突等问题避免启动失败后又去翻日志。这个命令不启动任何容器纯粹是解析配置生产环境上操作前多跑这一步能省很多时间。5.3 保留一份版本锁定记录镜像版本的组件版本是固定的但你在后期可能还会手动更新某个镜像。建议在 docker 目录下建一个.versions文件记录当前运行的镜像和 digest# 记录当前镜像 ID 和版本 docker images --digests | grep -E langgenius|dify .versions这样做的价值在于当某次升级或配置变更把系统搞坏时你手上有明确的回滚依据——哪些镜像在什么时间点是对的、应该恢复到哪个版本。配合 volumes 备份目录基本能做到任何翻车都有后悔药。从那以后我每次在服务器上动 Dify 之前都强制走一遍备份 volumes、执行 docker compose config 校验、确认 .versions 记录这四步流程一次都没跳过。希望帮到你。本文还有配套的精品资源点击获取