简介:面向 GitHub 访问不稳定用户的 dify 安装包,源自 2025 年 4 月 28 日的 GitHub 原版项目,打包为 zip 格式。压缩包共 2000 个文件,以 Python 源码(1404 个 py)为主,配合 368 个 JSON 配置、103 个 CSS 样式、41 个 Markdown 文档以及少量 JS、YAML、Shell 等文件,覆盖软件运行、前端界面、配置说明与脚本工具等完整层级,整体体积约 20.29MB。压缩包内主程序模块对应软件核心,包含运行所需的关键代码与资源。目前已有 264 人学习下载。对于受网络限制而无法稳定访问 GitHub 的开发者,此包可直接安装部署 dify,省去拉取源码的波折;同时包内附带的说明文档与配置模板,也可帮助用户快速理解项目结构与自定义设置,在离线或弱网环境下获得稳定的安装体验。
1. GitHub 不稳定,Dify 原版安装包到底该去哪拿
很多同学在部署 Dify 时卡在第一步:docker compose 编排文件还没见到,代码包在 GitHub 上就下不动了。dify安装包20250428gitub原版,这个命名本质上是 GitHub 上某个时间点的原版快照,把它做成离线包的人,显然也是被 GitHub 不稳定折磨过的那一批。Dify 是当下很常用的 LLM 应用开发平台,部署方式以 Docker Compose 为主,安装包其实由源码编排和镜像两部分组成。本文不讨论 Dify 平台功能,只解决一件事:在 GitHub 访问不稳定的环境下,怎么安全地拿到并部署一份原版安装包。
2. 先看懂 Dify 安装包:20250428 原版包含什么,怎么验真
2.1 安装包不是单个文件,而是一套 Docker Compose 编排
Dify 的官方部署方式是把整个应用拆成多个容器。从 GitHub 下载的 source code 包里,真正关键的是docker目录下的docker-compose.yaml和.env.example。这个目录还包含nginx、ssrf_proxy等子配置,以及middleware目录里存放的数据库初始化脚本。
很多人把“安装包”理解成一个可执行文件,这是误解。Dify 安装包 = 源码编排 + Docker 镜像。源码编排负责描述容器之间的依赖、端口挂载、环境变量;Docker 镜像才是真正跑起来的程序。GitHub 上能下载的只有编排和部分配置,镜像本体要另外从镜像仓库拉取。所以即使你成功下载了 20250428 源码包,没有镜像,服务照样起不来。
拿到压缩包后,先做第一眼检查:
unzip dify-main.zip cd dify-main/docker ls -1逻辑说明:unzip解压归档;cd进入编排目录;ls -1逐行列文件。这是判断安装包完整性的第一步。
参数说明:dify-main.zip是 GitHub 的 “Download ZIP” 默认命名,分支名不同,前缀会不同。20250428 这个打包日期只能说明打包动作的时间,不能说明分支,所以下载后最好先确认目录名再进下一步。
Dify 演进很快,docker-compose.yaml是入口,里面的镜像 tag 通常会写成dify-api:某个版本这种形式,反映原版版本。如果是 20250428 打包,镜像 tag 可能不是日期,而是某个语义化版本。你需要把编排文件里的镜像 tag 全部记录下来,作为后续拉取镜像的清单。
2.2 如何确认拿到的确实是原版:版本号、校验和、目录结构
“原版”两个字是这篇笔记的核心诉求。GitHub 不稳定的环境里,同学之间互相传安装包很常见,但传来传去容易混入改过的版本。我一般用三个维度验证。
第一,看版本标识。Dify 仓库里会有版本相关文件,例如根目录的version文件或docker目录里的标注。20250428 这种日期不是标准语义化版本,只是一次归档快照。所以不要只看文件名,要打开看内容。如果文件里直接写明 commit 号或版本号,把它记录到部署文档里,后续排查会省力很多。
第二,算校验和。用 sha256 对比官方 release 页面里的哈希值。但很多同学下载的不是官方 release 包,而是某同学自己打的包,这时候没有官方哈希可对比。退而求其次,找一个可信环境从 GitHub 拉一份,算一次哈希,把这个值记下来当基准。以后所有转发者都用同一个基准比对:
sha256sum dify-main.zip > dify-main.zip.sha256逻辑说明:sha256sum计算压缩包的 SHA-256 摘要。比对时执行sha256sum -c dify-main.zip.sha256,输出 OK 表示一致,FAILED 表示文件被改动或损坏。
参数说明:-c是校验模式,从文件读取摘要并比较。哈希相当于文件指纹,网盘中继、聊天工具传文件都可能改变内容,哈希不一致就说明包被动过或传坏了。
第三,核对目录结构和关键文件。原版的docker-compose.yaml顶部会有服务列表,包含api、worker、web、db、redis、weaviate、sandbox、ssrf_proxy、nginx这些定义。其中nginx是入口网关,db是 PostgreSQL,redis是缓存,weaviate是默认向量数据库。如果目录里混入额外启动脚本,比如install.sh,要小心,原版没有这种一键安装脚本。
2.3 版本与日期:20250428 对应什么,为什么要锁定日期
对于 Dify 这类迭代快的项目,锁定一个具体日期是防止部署完就失效的后悔药。20250428 这个名称大概率是发布者在 2025 年 4 月 28 日从 GitHub 抓取的 main 分支快照。这个快照不是官方 release,所以没有固定版本号。
我建议把这个归档当成一个临时基准:先部署跑通,后续再决定要不要升级。锁定日期意味着你的镜像 tag 和编排文件是配套的,不会出现 api 是 0.10.1、web 却停留在 0.10.0 的错位。Dify 的前后端接口耦合很紧,版本错位是典型的翻车现场。
如何锁定日期?最可靠的方式是用 commit 时间。你可以在能访问 GitHub 的机器上执行:
git clone https://github.com/langgenius/dify.git cd dify git log --before="2025-04-28" -1 --format="%H %cd" --date=short逻辑说明:这条命令列出 2025-04-28 之前最近的一个 commit 的 hash 和提交日期。拿到 hash 后,后续下载这个 commit 的归档包。
参数说明:--before按提交时间过滤;-1只取最近一条;--format="%H %cd"输出完整 hash 和日期。得到 hash 后可以用 GitHub 的 codeload 服务下载:
wget https://github.com/langgenius/dify/archive/<commit-hash>.tar.gz这里<commit-hash>是你查到的 40 位字符串,GitHub 支持按 commit hash 打包。如果你自己访问不了 GitHub,把这两条命令发给网络环境好的同学,让他们执行完把包传回来,这也是常见协作方式。
3. 获取原版安装包的四种路径:镜像加速、归档包、镜像仓库、内网中转
3.1 使用 GitHub 加速下载:把 URL 换成镜像域名
GitHub 直连不稳定时,最笨但最稳定的方法不是反复重试,而是用一个可以被正常访问的镜像域名。原理是给下载 URL 加一层中转,把github.com替换成镜像域名。但要注意,release 下载可能重定向到codeload.github.com等对象存储地址,所以镜像站需要支持完整的 URL 转发。
常见做法是把下载地址拼接在镜像域名后面,比如:
curl -L -C - --retry 3 -o dify-main.tar.gz \ https://your-mirror.example.com/https://github.com/langgenius/dify/archive/refs/heads/main.tar.gz逻辑说明:-L跟随重定向;-C -断点续传;--retry 3网络失败自动重试 3 次;-o指定保存文件名。
参数说明:-C -中的减号表示自动检测已有文件大小,从断点处继续。下载中断后重新执行,不会从头开始。your-mirror.example.com需要替换成你实际找的镜像域名,这个前缀会把原始 GitHub 地址整个作为参数转发。镜像站可能限流或过期,建议多准备两三个候选域名轮换。
这里还要强调一个细节:GitHub 网页可能偶尔打得开,但下载大文件时仍然中断,这不是你网络的问题,而是跨国链路的丢包。不要反复刷新网页,直接用命令行工具带重试参数下载,更容易成功。
3.2 从国内代码托管平台同步源码:git clone 替代下载
如果你需要的是源码包而不是 release 二进制,另一个更稳的路子是找国内代码托管平台上的同步仓库。很多开源项目会在多个平台自动镜像,你不需要从 GitHub 拉原始文件。
我在内网部署时常用的方式:在有网机器上直接 clone 国内镜像仓库,再打包传走。假设镜像仓库地址为https://git-mirror.example.com/dify.git:
git clone --depth 1 https://git-mirror.example.com/dify.git tar czf dify-20250428.tar.gz dify逻辑说明:--depth 1只拉取最新一次提交,减少传输量;tar czf把整个目录打包。这样得到的包与 GitHub 原版内容一致,但不包含.git目录的完整历史,体积大幅缩小。
参数说明:--depth 1会让后续无法用git log查历史。如果你需要锁定 20250428 时间点,就不要加这个参数,牺牲体积换完整性。镜像仓库的同步可能滞后,20250428 当天拉到的镜像可能还停留在前几天的状态,所以拿到包后要看版本标识,避免日期和内容对不上。
另外,如果你不需要整个仓库历史,只想要某一个 commit 的快照,可以在国内平台创建 fork 后,用 Web 界面“下载 ZIP”的方式导出,这种方式比 git clone 更轻量,缺点是拿不到历史提交记录。
3.3 从容器镜像仓库直接拉取镜像:避开 GitHub
实际上,Dify 的镜像主要在容器镜像仓库,而不是 GitHub Release。GitHub 不稳定,不代表镜像仓库也不稳定。如果你只需要把服务跑起来,完全可以先拉镜像,再用手里的编排文件启动。
Dify 的镜像 tag 一般和版本号绑定。你可以在能访问镜像仓库的机器上执行:
cd /path/to/dify/docker grep 'image:' docker-compose.yaml逻辑说明:这条命令会列出编排文件里所有服务引用的镜像地址。把每个image:对应的名称和 tag 记下来,这就是当前安装包需要的完整镜像清单。
参数说明:grep 'image:'是纯文本过滤,如果编排文件使用了环境变量拼接镜像 tag,需要手动看实际值。我见过有些版本把镜像 tag 写成dify-api:${DIFY_VERSION},这种情况下直接用 grep 看不出来,需要先加载.env再看:
export $(grep -v '^#' .env | xargs) docker compose config | grep 'image:'docker compose config会合并.env并输出最终生效的配置,这比直接 grep 靠谱。拿到镜像名后,用docker pull逐个拉取。如果你访问镜像仓库速度还可以,在目标服务器上直接执行docker compose up -d让 Compose 自动拉取才是最快路径。
3.4 内网中转:一台能访问外网的机器做跳板
前面几条路都受制于“当前机器能访问什么”。如果当前机器什么外网都不行,那就找一台能做中转的机器。常见拓扑是:你有一台云端服务器能访问 GitHub,家里服务器不能。那就在云端执行所有下载和打包操作,再通过rsync传到内网机器。
rsync -avP --partial \ dify-main.tar.gz dify-images.tar.gz \ user@目标机:/opt/dify-install/逻辑说明:rsync支持断点续传,适合传大文件;--partial保留部分传输的文件,避免中断后重头再来;-P等价于--progress --partial。
参数说明:-a归档模式,保留权限和时间戳;-v输出明细;user@目标机换成你的实际用户和地址。如果两台机器都是 Linux,这是最可靠的文件传输方式。Windows 中转机可以用系统自带的文件共享,但大文件容易在拷贝时静默损坏,传完务必做哈希校验。
以下是一个简单的路径对比表,便于你根据情况选择。
| 获取路径 | 适用场景 | 主要风险 |
|---|---|---|
| GitHub 镜像加速 | 只缺 release 包,单次下载 | 镜像站限流、过期 |
| 国内镜像仓库 clone | 需要完整源码或多次部署 | 同步滞后、内容与日期可能不匹配 |
| 容器镜像仓库直接拉取 | 已经有编排文件,只缺镜像 | 镜像 tag 与编排不匹配 |
| 内网中转 rsync | 内网完全不可出网,有云服务器 | 传输中断、缺少哈希校验 |
4. 离线安装 Dify 20250428 原版:从解压到健康检查
4.1 目录准备与文件校验
拿到安装包后,不要急着解压。先确认文件哈希与来源一致,避免传了一半的包浪费后面一小时。
sha256sum dify-20250428.tar.gz mkdir -p /opt/dify cd /opt/dify tar xzf /tmp/dify-20250428.tar.gz逻辑说明:sha256sum计算整个包的摘要,与来源方提供的基准值比对;mkdir -p创建安装目录;tar xzf解压。
参数说明:-p表示父目录不存在时自动创建。如果 tar 包解压时报unexpected EOF,说明文件不完整,需要重新获取。解压后目录里应该有独立子目录,例如dify/,注意不要解压出到处散落的文件。
进入 docker 目录,先备份示例配置:
cd /opt/dify/dify/docker cp .env.example .env ls -la逻辑说明:cp复制一份环境变量模板作为工作配置;ls -la查看完整目录内容,确认.env已经生成。
参数说明:.env.example是官方提供的默认模板,直接复制即可,里面包含服务端口、数据库密码、向量数据库类型等默认值。-la中的a会显示隐藏文件,避免看不到.env。
4.2 修改 .env 配置:端口、数据库、向量库
Dify 的.env是安装过程的黑匣子入口,许多玄学问题最后都指向这里。我一般只改必改项,其他保持默认,等启动失败再按日志调整。
vi .env逻辑说明:编辑配置文件。需要关注的参数如下表所示,但各版本字段名略有差异,以你手头的.env.example为准。
| 参数名 | 作用 | 我的建议 |
|---|---|---|
EXPOSE_NGINX_PORT | Web 入口端口 | 默认常为 80,若被占用改为 8080 |
POSTGRES_PASSWORD | 数据库密码 | 改成至少 16 位随机字符串 |
REDIS_PASSWORD | Redis 密码 | 改成独立随机字符串 |
SECRET_KEY | 会话和加密密钥 | 改成随机字符串,不能留空 |
VECTOR_STORE | 向量数据库类型 | 默认weaviate,无特殊需求不改 |
修改完保存退出。这里有一个关键点:SECRET_KEY一定要自己生成,不能用示例值。示例值是公开的,部署到公网上会有安全风险。生成随机字符串可以这样:
openssl rand -hex 32逻辑说明:openssl rand -hex 32生成 64 位十六进制随机字符串,适合做密钥。
参数说明:如果系统没有 openssl,也可以用python3 -c "import secrets; print(secrets.token_hex(32))"。把输出复制到.env中的SECRET_KEY值里。
4.3 离线导入 Docker 镜像:从 .tar 加载
如果你在内网机器上,且网络无法直接拉取镜像,就需要在有网机器上先把镜像打包成 tar 文件,再传到内网加载。
在有网机器上执行的打包命令:
for img in $(grep 'image:' docker-compose.yaml | awk '{print $2}'); do docker pull "$img" docker save "$img" -o "$(echo $img | tr '/:' '__').tar" done逻辑说明:循环提取编排文件中的镜像名,逐个docker pull下载,然后docker save保存为 tar 文件。tr '/:' '__'把镜像名中的斜杠和冒号替换为下划线,避免文件名出现特殊字符。
参数说明:awk '{print $2}'提取image:后面的内容。如果编排文件里镜像 tag 使用了环境变量,先执行docker compose config | grep 'image:'再套用这个循环。打包完成后把 tar 文件传到目标机器,批量加载:
for f in *.tar; do docker load -i "$f" done逻辑说明:遍历当前目录下所有 tar 文件并执行docker load,导入镜像到本地。
参数说明:docker load是从 tar 归档恢复镜像,docker save的逆操作。加载完可以用docker images | grep dify验证镜像是否齐了。这一步最耗时,也最容易因网络问题中断,建议在有网机器上分批执行,不要同时拉所有镜像。
4.4 docker compose up -d 启动与健康检查
镜像就绪后,启动服务:
docker compose up -d docker compose ps逻辑说明:docker compose up -d后台启动所有服务;docker compose ps查看每个容器的状态。
参数说明:如果这个版本的编排文件是docker-compose.yml(没有-),而你安装的是旧版 Docker Compose,需要先用docker-compose -v确认版本。现在 Docker 官方推荐用docker compose子命令,旧版需替换为docker-compose。
启动后过 1 到 2 分钟再检查健康状态,Dify 首次启动要初始化数据库和向量索引,速度取决于机器性能:
curl -I http://localhost/逻辑说明:发送 HEAD 请求,返回200 OK表示 Web 服务已就绪。
参数说明:如果修改了EXPOSE_NGINX_PORT为非 80 端口,这里要改成http://localhost:端口号。看到 200 后,打开浏览器访问 Web 界面,进入管理员账号初始化页面,安装过程才算结束。
5. 避坑/常见问题排查:GitHub 不稳定环境下装 Dify 最容易踩的 5 个坑
5.1 下载的包不完整,解压报错 unexpected EOF
现象:tar xzf或unzip执行到一半报unexpected EOF,文件释放残缺,后面运行 services 缺文件。
原因:文件下载被中断,但下载工具没有报错,甚至有些聊天工具会把大文件转存后截断,造成压缩包明明能打开但内部内容不完整。
解决:先删掉残缺包,重新下载,下载后必须执行sha256sum与来源基准比对。我见过很多次“团队里传了三次都是坏的”,就是因为大家只比对文件大小,没比对哈希。另外用curl -C -断点续传能救回部分中断的下载,但如果已经解压过,建议直接重下。
5.2 镜像版本和代码版本不一致,容器反复重启
现象:docker compose up -d后部分容器状态是Restarting,查看日志发现 api 容器报缺少环境变量或接口不匹配。
原因:代码包是 20250428 的 main 分支快照,但镜像 tag 可能对应了别的版本。比如有人把最新代码和旧镜像混在一起打包,或者从不同来源分别获取了代码和镜像。
解决:用docker compose config | grep 'image:'导出所有镜像 tag,再用docker image inspect langgenius/dify-api:<标签> | grep Created查看镜像构建时间,与代码快照日期对比。如果差很多天,就说明不配套。最稳妥的做法是在有网机器上重新拉取对应 tag 的镜像,重新打包导入。
5.3 忘记修改 .env 中的 SECRET_KEY,登录后一直报错
现象:Web 能打开,但管理员初始化时提交后报错,API 返回 500;过一会儿刷新又恢复,再操作又报错。
原因:SECRET_KEY用的示例值或在多容器环境下没同步。Dify 的 api 和 worker 需要读取相同的密钥,如果有两个实例配置不一致,会话无法持久化。
解决:在.env中生成随机SECRET_KEY,然后执行docker compose down && docker compose up -d,让所有容器重新读取环境变量。不要只 restart 单个容器,因为 worker、api、web 三者的环境变量必须保持一致。
5.4 端口冲突:80 端口被占,nginx 不启动
现象:docker compose ps中 nginx 容器显示exited,执行docker compose logs nginx看到bind: address already in use。
原因:宿主机 80 端口已被其他服务如系统自带 Web 管理面板占用,Dify 默认映射到宿主机 80,冲突导致容器退出。
解决:修改.env中的EXPOSE_NGINX_PORT为8080,然后docker compose up -d。注意如果只改EXPOSE_NGINX_PORT不影响容器内部 80 端口,它是宿主机到容器的映射,所以不需要改编排文件。
5.5 离线导入镜像后 compose 仍然尝试拉取
现象:镜像已经docker load完毕,但docker compose up -d仍然卡在Pulling状态,最终超时失败。
原因:docker compose默认会检查本地镜像是否与注册表同步,如果镜像本地存在但 tag 是latest且本地不是最新的,就会尝试拉取。另一种情况是编排文件中image写的是langgenius/dify-api:0.10.0,但本地镜像 tag 被保存时改名成dify-api:0.10.0,缺少仓库前缀。
解决:执行docker images看本地镜像名。如果确实存在,用docker tag补上完整名称:
docker tag dify-api:0.10.0 langgenius/dify-api:0.10.0逻辑说明:docker tag给本地镜像添加别名,使其匹配编排文件中的image名称。
参数说明:如果你本地镜像名和image字段已经一致,但仍然拉取,检查是否有pull_policy: always配置。Dify 新版编排中如有这个字段,将其删掉或改为missing,再用docker compose up -d启动。
6. 进阶:把 20250428 原版存档,后续增量更新不靠 GitHub
当你的内网第一次跑通 Dify 后,下一步不是高兴,而是把这个版本完整存档。我经历过一次教训:部署完三个月后想升级,发现手头只剩了 .env 文件,原始包和镜像清单都不知道丢哪了,只能重新上网找,结果网络环境还和之前一样差。所以我的习惯是,在/opt/dify/archive下建立固定的存档目录,每个版本一个子目录,里面至少放三样东西:源码 tar 包、镜像 tar 包、部署说明。
mkdir -p /opt/dify/archive/20250428 cp /opt/dify/dify-20250428.tar.gz /opt/dify/archive/20250428/ docker compose config --images > /opt/dify/archive/20250428/镜像清单.txt逻辑说明:docker compose config --images会输出当前编排文件引用的所有镜像列表,保存为文本文件。这是后续增量更新时比对版本的重要依据。
参数说明:如果你想把镜像也固化到本地,可以在有网机器上执行docker pull后用docker save打成 tar 存入同一个目录。不要只保存源码包,因为镜像不保存,未来网络恢复前依然无法部署。
增量更新时,优先找最新的编排文件而不是全部重新获取。但在 GitHub 不稳定的环境下,我不建议直接升级到 main 分支,而是先看镜像清单里的版本号,再去容器镜像仓库拉对应 tag 的镜像。把新镜像 load 进本地后,保留旧的镜像不删除,这样出问题可以随时回滚。
docker tag langgenius/dify-api:<新版本> langgenius/dify-api:<新版本>-backup docker compose pull api docker compose up -d --remove-orphans逻辑说明:docker tag先给现有镜像打一个 backup 标签,避免升级失败后无路可退;docker compose pull api按编排文件拉取新镜像;docker compose up -d --remove-orphans启动新配置并清理多余容器。
参数说明:--remove-orphans会把编排文件中已经不存在的服务容器删除。如果只是小版本迭代,也可以不加这个参数,保留旧容器手动排查。
最后说一个习惯:每次拿到新安装包,不要急着部署。先花两分钟看目录结构,算一次哈希,提取一次镜像清单,这几步能用十分钟避免之后的一小时排障。GitHub 不稳定导致的下载问题,本质不是玄学,而是链路丢包和工具选择的问题。离线的方案做扎实后,网络波动反而成了最不重要的环节。希望这篇笔记能帮到你,让你在部署 Dify 时少走一段冤枉路。
本文还有配套的精品资源,点击获取