简介:作为一款开源软件/插件,Dify官方在GitHub发布安装包,并以zip格式提供下载,面向需要快速搭建或定制AI应用开发平台的开发者与运维人员;无论是个人学习还是团队部署,直接获取该压缩包都能省去从源码仓库逐文件下载的繁琐,同时保留完整的Dify主程序框架。包内共收录2000个文件,整体大小约20.25MB。其中Python源码占1337个,承担核心后端逻辑;JSON配置366个,用于系统参数与数据定义;另有116个CSS样式、84个JS脚本、38个Markdown文档、32个YAML编排文件及12个Shell脚本,分别覆盖前端界面、项目文档与自动化部署。该资源在CSDN已有2702人学习或下载,实用关注度较高。解压后即为Dify项目主体(dify-main),包含样式资源、页面模块、配置示例及文档说明;既可按照目录结构快速完成安装,也能借此分析项目架构,为二次开发与排错提供清晰参考,尤其适合关注AI应用开发平台构建、需要动手实践源码级安装的技术人员。
1. 自己动手装 Dify:官方安装包为什么值得折腾
如果你在 GitHub 上搜 dify 官方安装包,第一感觉可能是失望:没有看到常见的 .exe 或 .zip,而是一堆源码文件和 docker-compose.yaml。这不是包装有问题,而是 dify 本身就是一套由前端、后端、数据库、向量库组成的软件系统,安装包只是整个仓库的入口。把它跑起来后,你可以用可视化方式搭建知识库问答、聊天助手、AI 工作流,甚至把模型供应商和插件机制集成进去,省掉大量胶水代码。适合谁?不想从零写 LLM 应用后端、又需要私有化部署的人。我最初把源码包当成自解压程序,下载方式选错,后面所有步骤都成了玄学,结果在分支和环境变量上踩了不少坑。这篇笔记把下载、部署、避坑和升级串起来,照着做能少走弯路。
2. 从 GitHub 下载官方安装包:三种拿法的区别与适用场景
官方安装包的下载方式直接决定后续部署路径。源码压缩包适合二次开发和本地调试,Docker Compose 编排文件适合直接上线跑服务,Release 页面上的 tag 则负责把源码和镜像锁到同一个版本。很多人第一步就错在把 Source code 当成安装包,后面怎么做都不对劲。理清这三种拿法之间的区别,是避免翻车的前提。
2.1 源码压缩包:适合二次开发,别当自解压程序用
GitHub 仓库首页的 Code 下拉菜单里有一个 Download ZIP,点一下就能把整份源码打包下载。这个操作听起来方便,但很多人踩的第一个坑就是把这份源码当成安装包。源码包里是 api、web、docker、tests 这些目录,不是一个可以直接启动的程序。api 后端是 Python 项目,需要安装一堆依赖;web 前端需要单独构建;数据库、向量库、Redis 一个都不能少。把这套目录丢进 nginx 或者随便一个容器里就跑,是不现实的。
源码压缩包真正的使用场景是二次开发。比如你想改后端接口的返回格式、给前端加一个自定义界面、或者研究某条工作流的具体实现,这时源码是基础。常见做法是先克隆仓库,再切换到你想要的版本标签:
git clone --depth 1 https://github.com/<owner>/dify.git cd dify git tag -l逻辑说明:git clone 是获取源码最稳的方式,比浏览器下载 ZIP 更不容易出现文件不完整的问题。地址里的 是占位符,实际使用时要替换成你在仓库页面地址栏里看到的属主名。--depth 1 表示浅克隆,只拉取默认分支的最近一次提交,整体数据量比完整仓库小很多,网络差的时候重试成本也更低。
参数说明:--depth 1 会丢掉完整历史,所以 git tag -l 只能看到包含在当前浅克隆里的标签。如果之后要切换到某个历史 tag,需要先执行 git fetch --unshallow 拉全历史,再 git checkout 。不同项目的 tag 命名风格不一样,有的带 v 前缀,有的不带,要以 Release 页面里的实际显示为准。
如果已经下载了 ZIP 文件,也不是完全不能用,但要注意传输完整性。ZIP 一旦下载失败,解压时大概率报 CRC 错误。Git clone 本身带完整性校验,出错后重新执行一次就能继续,比反复下 ZIP 要省心得多。
2.2 Docker Compose 编排文件:官方最推荐的生产级拿法
大多数人在 GitHub 上找 dify 官方安装包,真正需要的是 docker-compose.yaml 和 .env.example 这两个文件,它们一般在仓库的 docker 目录下。Compose 文件描述了这个系统里有哪些服务、镜像从哪儿来、端口怎么映射、数据卷怎么挂载;.env.example 则是所有环境变量的模板。只下载 docker-compose.yaml 一个文件是不够的,因为 compose 文件里还会引用 nginx 配置目录、额外工具脚本、或者其他配置文件,目录结构不完整会在启动阶段报挂载卷找不到,提示你只拿到了局部。
更省心的做法是把整个 docker 目录一并拿下来。这里给出下载两个核心文件的命令:
mkdir -p dify-deploy && cd dify-deploy curl -L -O https://raw.githubusercontent.com/<owner>/dify/main/docker/docker-compose.yaml curl -L -O https://raw.githubusercontent.com/<owner>/dify/main/docker/.env.example mv .env.example .env ls -l逻辑说明:curl 的 -L 参数必须加上,GitHub raw 链接会经过重定向,不加 -L 拿到的可能是一段 JSON 报错或者空文件。-O 表示把内容保存成远程 URL 里的文件名,避免你手滑改成别的名字。下载完成后,要把 .env.example 复制或改名为 .env,因为 Docker Compose 默认读取同目录下的 .env 文件;如果这个文件不存在,所有变量都变成空值,数据库密码、密钥全部失效,启动时会出现各种诡异报错。
参数说明:raw.githubusercontent.com 路径里最后一段是默认分支名。很多项目保持 main,但老项目可能是 master,具体看仓库的默认分支。分支名只影响路径是否有效,不影响文件内容。ls -l 用来确认文件大小和权限,如果 .env.example 是 0 字节,说明下载失败了,重新执行 curl 前要先删掉这个残留文件。
还需要注意,如果 compose 文件里 volumes 段落映射了 nginx/conf.d 之类的目录,那么同级的 nginx 配置目录也要一起下载。判断依据不是猜,而是打开 docker-compose.yaml,看 services 下面每个服务挂载了哪些宿主机路径,把对应文件补齐。这一步做不到位,后面 Web 服务大概率打不开。
2.3 Release 资产与源码 tag:找官方安装包的正确入口
打开 GitHub 仓库的 Releases 页面,能看到一堆版本号,每个版本下面通常有 Source code (zip) 和 Source code (tar.gz) 两个链接。这两个链接只是 GitHub 自动生成的源码归档,不是部署包。真正要关注的是版本号本身,也就是 tag 名。容器化项目的标准做法是:某个 tag 对应一组镜像标签,镜像标签和源码 tag 一起构成一个完整的可安装版本。
也就是说,official 安装包并不是一个单独的压缩文件,而是“源码 tag + 镜像标签 + 编排文件”的组合。确认一个版本是否完整,可以先检查组编排文件里的镜像标签是否一致:
grep 'image:' docker-compose.yaml逻辑说明:这条命令把 compose 文件里所有 image 字段列出来,你会看到 api、web、worker 等各服务的镜像引用。如果它们都在用默认的 latest,说明这是开发配置。生产部署时应该把镜像标签统一改成 Release 页面上看到的某个具体版本号,避免某次 docker compose pull 拉到了新镜像,而其他服务还是旧的,造成前后端版本不一致。
参数说明:latest 不是版本,它是随项目维护者的推送不断变化的指针。实际生产环境里,api 镜像可能被自动拉到新版本,web 镜像还是旧的,看起来页面能打开,但保存工作流时接口报错。这种半新半旧状态最难排查,所以一定要把镜像标签锁定到具体版本。
如果你打算基于源码包来部署,还需要把本地代码切到对应的 tag 上:
git checkout <tag> git submodule update --init --recursive 2>/dev/null逻辑说明:git checkout 让工作区进入该版本的源码快照。第二行是更新子模块,有些项目用 submodule 管理内部组件,不更新的话目录里可能是空的。如果项目没有子模块,这行输出为空或直接返回,忽略即可。
参数说明: 是占位符,填写 Release 页面的实际版本字符串。注意,源码 tag 和镜像标签最好保持一致。比如你在 Release 看到的是 1.x.x,那就把 docker-compose.yaml 中所有 image 标签都改成 1.x.x,避免源码和镜像一个前一个后,最终代码行为和你预期的完全对不上。
3. 部署 Dify 服务:把官方包跑起来的完整流程
拿到安装包只是第一步。这一章讲的是把 compose 文件变成一组正在运行的容器,从环境检查开始,到 .env 配置,再到页面初始化。部署过程中最大的问题是状态验证不完整:容器都起来了,不等于系统能正常提供服务。所以每一步都要有明确的检查动作。
3.1 环境准备:内存、Docker 与端口占用检查
Dify 不是一个单一容器,而是一组服务:api 是后端入口,web 是前端静态页面,postgres 存业务数据,redis 做缓存,向量库负责知识库检索。所有容器都在同一台机器上跑时,资源不够会以很隐蔽的方式暴露出来——postgres 初始化慢,nginx 等待超时,api 被系统 OOM Kill。因此第一件事不是启动,而是确认宿主环境够不够用。
docker --version docker compose version free -h df -h /var/lib/docker逻辑说明:docker --version 确认 Docker 客户端和服务端正常。docker compose version 检查 compose 插件是否安装,如果提示没有 compose 子命令,说明缺失 docker-compose-plugin。free -h 看内存,建议至少有 4GB 可用内存;如果还要本地跑模型推理,这个值要更高。df -h /var/lib/docker 看 Docker 数据目录剩余空间,拉镜像和日志增长都会占用这里。
参数说明:free -h 输出里的 available 列才是真正能给新容器用的内存,不是 total。如果 available 长期低于 2GB,容器随时可能被杀掉。df 命令里的 /var/lib/docker 是默认数据目录,如果你调整过 daemon.json 里的>ss -lntp | grep -E ':80|:443'
逻辑说明:默认 Web 入口是 80 端口。这条命令列出正在监听的端口,如果 grep 到了内容,说明 80 或 443 已经被别的服务占用。这种情况下不需要卸载已有服务,只需要在 .env 里把 Web 端口改掉。
参数说明:云服务器上即使本地端口没有冲突,外部也可能访问不了。安全组的出站入站规则需要在云管理控制台单独放行,那是平台层面的配置,和容器无关。所以本地端口通了不代表公网能访问,这两件事要分开排查。
3.2 配置 .env 并启动:SECRET_KEY 与密码是重点
.env 文件控制 Dify 的基础参数。模板里已经填好大部分默认值,但有三项必须自己动手:SECRET_KEY、POSTGRES_PASSWORD、以及初始化管理员用的临时密码。直接沿用模板默认值,短时间可能能跑通,后面做升级或者多实例部署时,会因为密钥不统一而出大问题。
cp .env.example .env openssl rand -hex 32 vim .env逻辑说明:openssl rand -hex 32 生成一个 64 字符的十六进制串,复制到 .env 的 SECRET_KEY 变量。这个值影响会话加密、密码哈希和签名逻辑。如果你的系统有多个副本,它们必须完全一致,否则登录状态无法互相识别。vim 打开 .env 后,找到这三个变量的位置,逐个替换。
参数说明:POSTGRES_PASSWORD 是数据库密码,改成强密码,不要和 SECRET_KEY 相同。INIT_PASSWORD 是首次初始化管理员账号的临时密码,如果 .env 模板里没有这个变量,就不用管,以后台页面实际显示为准。另外留意端口相关变量,比如 .env 注释里带有 PORT 的项,这些变量最终决定浏览器访问端口。
配置完成后启动:
docker compose up -d逻辑说明:-d 表示后台运行。第一次执行会拉取 compose 文件里的所有镜像,可能看起来像卡住,其实是在下载。下载完成后容器按依赖关系陆续启动。千万不要只通过 docker compose ps 看有没有容器,还要看状态是否为 healthy。
参数说明:如果 compose 文件里的镜像标签是 latest,生产环境建议先改成固定 tag。如果想预先拉取镜像再启动,可以运行 docker compose pull,单独把镜像拉到本地;这只下载不启动,之后 up 会快很多。
3.3 验证服务与创建首个应用
启动后不要急着打开浏览器,先用命令把后端状态看清楚。api 是整个系统的核心,它如果没起来,页面登录了也发不出任何消息。
docker compose ps docker compose logs api -f逻辑说明:docker compose ps 输出每个服务的运行状态。healthy 表示健康检查通过,Restarting 或 unhealthy 都是异常。logs api -f 是跟踪后端日志,看到 Application startup complete 或类似输出,说明后端已经准备就绪;如果一直报错或反复退出,回到上一节检查 .env。确认后端就绪后,可以用 curl 快速验证前端入口:
curl -I http://localhost:80/install逻辑说明:-I 只请求响应头,返回 200 说明 nginx 转发链路正常;返回 502 说明 nginx 后面的 web 或 api 还没就绪。如果改过端口,把 80 换成实际端口。这一步能帮你快速判断 Web 打不开是容器问题还是服务问题。
浏览器访问 http://<服务器IP>:<端口>/install,第一步创建管理员账号,第二步连接模型供应商。如果没有可用的模型 API Key,应用即使创建成功也无法真正对话。建议先把模型供应商 Key 准备好,在“设置-模型供应商”里测试通过后,再回到应用编排里选择模型。这里最容易出的问题是供应商接口超时,具体排查在第 4 章。
4. 避坑排查:下载安装 Dify 常见的五个翻车现场
这一章整理我实际部署中遇到的五个高频问题。每条按现象、原因、解决三步写,你可以直接对照现象找到对应处理方式。
4.1 GitHub 下载慢或中断,源码包不完整
现象:浏览器或 wget 拉源码包时下到一半就断,文件停留在几十 MB,解压时报“unexpected end of file”。
原因:普通 HTTP 下载遇到网络波动不会自动断点续传,源码包是整包传输,一次失败就得重新下载。国内网络访问 GitHub 资源时,这种情况尤其常见。
解决:换用 git clone 代替下载 ZIP。git 按对象传输,自带完整性校验,而且失败后重试成本低。执行以下命令:
git clone --depth 1 https://github.com/<owner>/dify.git cd dify git status逻辑说明:--depth 1 只拉取默认分支的最新提交,避免下载完整历史导致的数据量过大。git status 输出 working tree clean 表示文件完整。如果 clone 中途失败,先删除残留目录再重新 clone,不要在一个不完整的仓库上继续操作。
参数说明:如果 clone 一直失败,还可以在执行 clone 前设置 git 的 http postBuffer 或降低压缩等级,但绝大多数情况改镜像地址才是直接方案。我这里不展开镜像地址,因为不同网络环境差异很大,你自己搜一下更适合当前情况的 GitHub 加速方式。
4.2 docker compose up 后 Web 服务打不开
现象:docker compose ps 里容器都跑着,浏览器访问却返回 502 Bad Gateway,或者直接显示连接被拒绝。
原因:最常见的是宿主环境里 80 端口已经被占,也可能是 nginx 容器启动时后端的 api 或 web 服务还没就绪,反向代理连不上上游。
解决:先看 nginx 日志,确认问题出在哪一层:
docker compose logs nginx docker compose ps逻辑说明:如果日志里出现 bind(): Address already in use,说明端口冲突。打开 .env,找到端口相关的变量,例如 EXPOSE_NGINX_PORT 这一类,改成 8080,然后强制重建 nginx 容器:
docker compose up -d --force-recreate nginx参数说明:--force-recreate 会销毁旧容器并按新配置重建,端口映射随之生效。如果 nginx 日志里显示连接上游失败,说明 web 或 api 还没就绪,等待几十秒后执行 docker compose restart nginx,让它重新发起连接。端口变量名可能随版本变化,以你的 .env 里注释为准;找不到时可以直接改 docker-compose.yaml 中 nginx 服务下的 ports 字段,例如 "8080:80"。
4.3 模型供应商连不上:API Key 与网络出口
现象:在模型供应商页面点“测试连接”,等了一段时间后报 timeout,或者直接返回 invalid api key。
原因:多数情况下是 Key 复制时带了空格或换行,或者是把 Key 填错了供应商字段。另一种原因是容器所在网络的 DNS 解析不了模型供应商的 API 域名,尤其是在内网服务器上部署时。
解决:先在设置页重新粘贴 Key,确认没有多余字符。然后在 api 容器里做一次域名解析检查:
docker compose exec api sh -c "getent hosts api.your-llm-provider.com"逻辑说明:把命令里的域名替换成你实际使用的模型服务地址。如果没有输出解析结果,说明容器 DNS 有问题。你可以在 compose 文件中 api 服务下增加 dns 字段,指向公共 DNS 服务器,然后重启 api 容器。如果模型服务在内网,直接用内网 IP 作为 base URL,绕开 DNS 解析会更省事。
参数说明:不要为了测试连通性去修改容器默认的网络模式,那样会破坏容器间互相访问,api、postgres、redis 之间的连接会全部中断。遇到域名解析不了,优先加 dns 配置或者改 base URL 为 IP。
4.4 数据库连接拒绝:Postgres 初始化顺序惹的祸
现象:api 容器启动后反复退出,日志里出现 connection refused,并且后面的地址指向 127.0.0.1:5432 或对应数据库服务名。
原因:Postgres 第一次启动时需要初始化数据目录,这个过程可能持续几十秒。api 容器启动得早,连不上数据库就报错退出。另一种情况是 .env 里改了 POSTGRES_PASSWORD,但数据库卷里保存的还是旧密码,导致认证失败。
解决:先看 Postgres 状态:
docker compose ps postgres如果状态是 Restarting,再看日志:
docker compose logs postgres | tail -20逻辑说明:日志里出现 database system is ready to accept connections 才说明 Postgres 初始化完成,在此之前的报错都是正常等待。如果看到 password authentication failed,说明密码不一致。这种情况多为首次部署时改了密码但没有重建数据库卷。在确认还没有真实数据时,可以直接重置:
docker compose down -v docker compose up -d参数说明:-v 会删除所有命名卷,包括数据库和向量数据,只适合还没有写入真实数据的阶段。一旦开始录数据,绝对不要直接执行这条,必须先备份。
4.5 升级后应用数据消失:没做备份直接拉新镜像
现象:升级成功后,登录平台发现原来的应用列表是空的,历史对话记录也不见了。
原因:新版本镜像启动后可能自动触发数据库迁移,迁移过程遇到旧数据兼容问题,导致部分表被重建或清空。还有一种情况是升级命令里用了 docker compose down -v,把数据卷直接删掉了。
解决:升级前强制备份数据库。最简单的方式是导出一份 SQL 文件:
docker compose exec postgres pg_dump -U postgres dify > dify_backup.sql逻辑说明:这条命令是逻辑备份,生成一个可读的 SQL 文件,换机器也能导入。用户名和库名要改成你 .env 里实际配置的值。升级后如果数据不对,先看 api 日志里有没有 migration 相关报错,再手动执行数据库迁移:
docker compose exec api flask db upgrade如果迁移仍然无法解决问题,就用备份文件恢复数据库:
docker compose exec -T postgres psql -U postgres dify < dify_backup.sql参数说明:-T 表示不分配伪终端,适合重定向输入。恢复前建议先停掉 api 服务,避免它继续往数据库里写入新数据,造成恢复后的数据混乱。备份文件要存放在宿主机器上,不要放在容器里,因为容器重建后卷里的内容会丢失。
5. 进阶收尾:离线交付与升级回滚技巧
5.1 官方安装包离线交付:镜像瘦身与内网导入
很多企业内部环境不允许服务器直接访问外网。容器化设计的优势在这里体现得很明显:只要在一台能联网的机器上拉齐镜像,导出成一个 tar 包,再拿到内网加载即可。关键是让镜像标签和 compose 文件保持一致。
docker compose images docker save -o dify-images.tar dify-api:<tag> dify-web:<tag>逻辑说明:docker compose images 列出当前配置里实际使用的镜像和标签,然后把需要导出的镜像逐个写入 save 命令。不要手工猜标签名,直接从第一条命令的输出里复制,减少笔误。tar 包会比较大,这是正常的,因为镜像层是未压缩存储。
内网导入时执行:
docker load -i dify-images.tar导入后镜像就出现在内网机器的 Docker 里,之后 docker compose up 不会再去外网拉取。如果内网机器完全隔离,还要检查 .env 里是否有需要外网访问的模型供应商地址,如果是,就改成内网可达的模型服务地址,或者直接使用本地模型。
5.2 升级验证与回滚:先备份,再切版本
升级最容易翻车的地方不是代码,而是没有可回退的备份。很多人只备份了数据库,忽略了 .env。实际上 SECRET_KEY 一旦变化,数据库里的加密信息和会话令牌都会失效,等于把系统弄得半死不活。所以升级流程的第一步是备份整个 docker 目录和 .env。
cp -r docker dify-backup-$(date +%F) docker compose pull docker compose up -d docker compose ps逻辑说明:第一行把 docker 目录连同 .env 一起拷贝到带日期的备份文件夹,这是最后的“后悔药”。第二行拉新镜像。第三行重建容器。第四行确认容器状态。升级后不要急着关终端,先观察 api 日志,确认没有 migration 报错,再打开页面验证应用列表和对话记录是否都还在。
如果升级失败,先停掉当前服务:
docker compose down然后恢复备份的 .env 和 compose 文件,把镜像标签改回旧版本,再执行 docker compose up -d。一旦数据库已经发生过迁移,仅仅回滚镜像还不够,可能还要用备份的 SQL 文件恢复数据库。这也是我反复强调备份要站在最前面的原因。
我最早一次升级时只改了镜像标签,没备份数据库,结果迁移失败后应用列表全空,只能重新初始化。从那以后我每次升级都强制走一遍备份流程:先导 SQL,再拷贝 docker 目录,接着才动版本号。希望这篇笔记里的下载方式和坑点能帮到你,在自己动手装 Dify 时少碰几次壁。
本文还有配套的精品资源,点击获取