群辉 NAS 部署 Dify 避坑指南:安装包 + Docker Compose 实践
简介:面向群辉NAS用户,这份资源是Dify应用的完整部署安装包,旨在简化在群辉设备上安装配置Dify的复杂流程,适合具备基础Linux命令行与群辉套件操作经验的技术人员。压缩包共2000个文件,大小20.2MB,核心包括1369个Python脚本、367个JSON配置、107个CSS样式、67个JavaScript前端逻辑,以及22个YAML部署配置文件、12个Shell安装脚本,辅以Markdown说明文档,整体覆盖了从后端服务到前端界面的全部部署所需。目前已有1366人学习/下载。借助该安装包,用户无需自行拼接资源,可按包内配置模板调整端口、权限与启动参数,快速将Dify运行起来;同时,资源目录按前端、后端、配置与脚本分类,结构清晰,为后续二次开发、环境排错提供了便捷参考。若部署中遇到系统权限或网络环境问题,包内脚本和配置文件同样能帮助快速定位,降低手动排查难度,尤适合希望在自己群辉上搭建自有Dify服务的用户。
1. 群辉上跑 Dify:为什么我最终选了“安装包”而不是在线脚本
很多人在部署 Dify 时第一反应是去跑官方一键安装脚本,但真到了群辉 NAS 上,你会发现这套思路不一定走得通。群辉的系统盘、套件权限、Container Manager 的项目文件路径,都跟一台 Ubuntu 服务器有差别,脚本里默认的 /var/lib 路径往往在群辉上直接翻车。我反复试了几次之后,最终改用「官方 release 安装包 + 手工调整 Compose 编排文件」的方式,在群辉上把 Dify 平稳跑了起来。这篇笔记面向想在群辉上部署 Dify 的从业者,覆盖从下载安装包、拆分 docker-compose.yaml、启动服务到接入本地模型的完整过程,并附上我在内存不足、权限异常和端口冲突上踩过的具体坑。
2. 部署前确认三件事:群辉型号、Docker 与资源门槛
在把安装包下载到群辉之前,先花十分钟确认三件事,能省掉后面大量排错时间。Dify 不是单个容器,而是 api、worker、web、db、redis、sandbox 这一组容器组成的编排项目,任何一个环节在群辉上出问题,表现得像整个系统不可用。群辉有 x86 和 ARM 两个平台,官方镜像对 ARM 的支持不稳定,所以第一个要查的是机器架构,其次才是内存和 Docker 环境。
2.1 群辉 Docker 环境检查:Container Manager 与传统套件的区别
群辉从 DSM 7.2 开始,容器工具更名为 Container Manager,界面和 API 与旧版 Docker 套件差别不小。我用的 DS920+ 上是 Container Manager 20.10.23-1711,跟 Docker Engine 的兼容性没问题。如果你的群辉还停留在 DSM 6,只有旧版 Docker 套件,建议先把 DSM 升到 7.2 或手动更新 Docker 版本,否则 compose v2 语法和 healthcheck 配置都会在启动阶段报错。
# 群辉 SSH 终端确认 Docker 与 Compose 插件版本
docker --version
docker compose version
这两条命令输出本身不重要,重要的是第二条不能报 command not found 。Container Manager 自带 compose v2 支持,结果显示类似 Docker Compose version v2.17.3 才说明你可以直接用 docker compose 管理项目。如果只有老的 docker-compose 单文件版,后续导入 compose 项目时语法兼容性会差一些,特别是 deploy.resources.limits 这类字段不一定被解析。
2.2 内存与存储预算:Dify 8G 内存的下限不是上限
Dify 官方要求内存不低于 8G,但这是「跑起来」的下限,不是「跑得舒服」的标准。我在 8G 内存的 DS920+ 上实测,Dify 全家桶启动后 Docker 统计内存长期在 4.2G 到 4.8G 之间波动,这还没算 DSM 系统本身和 SMB 共享服务吃掉的部分。也就是说,机器至少有 16G 内存才能保证 Dify 与群辉其他套件互不挤压。
若执意在 8G 内存上跑,也不是不行,但要接受三个后果:加载模型回复时 Web 端偶发超时、worker 在并发任务多时被 OOM Killer 杀掉、群辉自带的相册索引明显变慢。我把 swap 文件调到 4G 之后情况缓和不少,但 swap 只能缓解内存压力,解决不了 CPU 和磁盘 IO 的争抢。存储上建议把 Dify 项目目录放在 SSD 存储空间,机械盘跑 Postgres 的首次迁移会慢到让你怀疑机器卡死了。
2.3 版本选择:下载安装包前先锁定版本号
Dify 的安装包本质上是 GitHub 上 dify 仓库 docker 目录下的整套文件,包括 docker-compose.yaml、.env.example、ssrf_proxy 配置。下载之前我建议先锁定一个版本号,不要直接拉 latest。Dify 迭代频繁,镜像名不带 tag 或者用 latest,在群辉这种不常更新镜像的环境里,前后端版本不一致会引发兼容问题。
我这次用的是 0.9.2 版本对应的安装包,镜像全部锁在 0.9.2 上。理由是这套编排文件里 Postgres 15 和 Redis 6 的依赖已经明确,不会像最新版那样引入新的向量库配置,降低首次部署的不确定因素。
# 以 0.9.2 为例,锁定版本下载安装包(群辉 SSH 中执行)
cd /volume1/docker/dify
curl -L -o dify-docker-0.9.2.tar.gz \
https://github.com/langgenius/dify/archive/refs/tags/0.9.2.tar.gz
tar -xzf dify-docker-0.9.2.tar.gz
mv dify-0.9.2/docker/* ./
这段脚本做了三件事:进入群辉的 docker 共享目录、下载指定 tag 的源码包、把 docker 子目录里的文件解压到当前工作目录。注意 /volume1 对应群辉第一个存储空间,机器型号不同可能变成 /volume2 或 /volume3。选源码包而不是 git clone,是因为 clone 会拖下整个仓库历史,占空间且网络不稳时经常半途中断。
3. 安装包目录结构拆解:docker-compose.yaml 与 .env 不能动错文件
解压完成后,docker 目录下有一堆文件。很多人第一反应是找某个「一键安装包」双击执行,但在群辉上正确的做法是理解这套编排文件的结构。这章我拆解最关键的 docker-compose.yaml 和 .env,讲清楚哪些是必须保留的文件、哪些参数在群辉上必须改。
3.1 文件清单与目录约定
Dify 安装包的 docker 目录下核心文件包括:docker-compose.yaml、.env.example、docker/ 子目录、ssrf_proxy 目录。docker-compose.yaml 定义服务清单,.env.example 是环境变量模板,实际部署时复制为 .env 再编辑。docker/ 子目录里是构建镜像用的 Dockerfile 与 nginx 配置。
| 文件或目录 | 用途 | 群辉上是否改 |
|---|---|---|
| docker-compose.yaml | 编排服务定义 | 微调端口与资源限制 |
| .env.example | 环境变量模板 | 复制为 .env 后修改 |
| docker/nginx | 前端反向代理配置 | 默认不改 |
| ssrf_proxy | SSRF 防护代理 | 默认不改 |
| Dockerfile | 镜像构建文件 | 不删,否则 build 报错 |
不要删除这些文件,即使你觉得用不上。compose 文件里如果有 build 指令,Container Manager 会按路径找 Dockerfile,删了就构建失败。
3.2 .env 环境变量:端口、密钥、Postgres 账号
.env 是部署时最需要手工调整的文件。模板默认把系统入口设在 80 端口、前端设在 3001 端口。这在纯净 Linux 服务器上没问题,但群辉上 80 端口可能被 Web Station 占用,3001 也常见被其他套件抢走,第一步就是改端口。
# 复制模板并修改关键配置
cp .env.example .env
vi .env
# 重点修改这几项
EXPOSE_NGINX_PORT=18080
EXPOSE_WEB_PORT=13001
POSTGRES_PASSWORD=YourStrongPassword
SECRET_KEY=YourRandomSecretKey
参数含义:EXPOSE_NGINX_PORT 是 Dify 对外的 Web 入口端口,改到 18080 避开 80 冲突;EXPOSE_WEB_PORT 是前端容器端口,改成 13001 避免被占。POSTGRES_PASSWORD 和 SECRET_KEY 是安全相关参数,尤其 SECRET_KEY,保持默认值等于把你的会话密钥公之于众,必须自己改。
注意:SECRET_KEY 不要用 .env.example 里的默认值,否则任何拿到安装包的人都能推导出你的会话签名密钥。
.env 里还有 VECTOR_STORE 和 VECTOR_STORE_API_KEY,默认不启用独立向量库时用 Postgres 自带 pgvector,这些项可以留空。若后续要接 Qdrant 或 Weaviate,再回来补全。
3.3 服务依赖关系:api、worker、web、db、redis、sandbox
docker-compose.yaml 定义了 7 个核心服务:api、worker、web、db、redis、sandbox、ssrf_proxy。api 负责后端接口和知识库检索;worker 负责异步任务;web 是前端静态页面;db 是 Postgres 15;redis 做缓存和消息队列;sandbox 是代码执行沙箱;ssrf_proxy 拦截外呼请求。
# docker-compose.yaml 中 api 服务的关键片段(0.9.2)
api:
image: langgenius/dify-api:0.9.2
restart: always
environment:
MODE: api
SECRET_KEY: ${SECRET_KEY}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
DB_DATABASE: ${DB_DATABASE}
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
REDIS_PASSWORD: ${REDIS_PASSWORD}
CELERY_BROKER_URL: ${CELERY_BROKER_URL}
depends_on:
- db
- redis
这段的关键在 depends_on。depends_on 只控制启动顺序,不等待数据库真正就绪。Postgres 初始化未完成时 api 会先启动然后报连接错误退出。好在 compose 里 api 和 worker 都配了 healthcheck,后面通过 docker compose ps 可以判断状态。
4. 在群辉上拉起 Dify:Compose 项目导入到首次访问
这章把启动过程拆成四步:导入项目、启动等待、初始化账号、跑通第一个知识库应用。每步都有对应的验证方法,不凭感觉往下走。
4.1 用 Container Manager 导入 Compose 项目
进入 Container Manager 的项目页面,新建项目,把 docker-compose.yaml 内容粘贴进去,项目名建议叫 dify。文件位置选到放 .env 的目录,Container Manager 会读取 .env 填充环境变量。
# 不想用图形界面的可以在 SSH 里执行
cd /volume1/docker/dify
sudo docker compose up -d
两种方式效果相同。我倾向于图形界面,因为 Container Manager 会直接展示项目内存占用和容器健康状态,排查时不用敲命令。导入时勾选「启用自动启动」,群辉重启后容器才会自动拉起。
提示:Container Manager 里显示容器 running,不代表 Dify 已初始化完成,判断标准是 api 日志里出现 Database initialization succeeded。
4.2 启动顺序与健康检查:等 postgres 就绪再访问
Dify 首次启动时,api 容器会执行数据库表结构初始化,前提是 postgres 容器的 pgvector 扩展已创建完成。你如果启动完立刻访问,大概率看到 502 或「数据库未初始化」提示。
# 查看容器启动状态
docker compose ps
# 确认 api 日志里的迁移结果
docker compose logs api | tail -n 50
日志中看到 Running migrations 和 Database initialization succeeded,说明 API 已与数据库建立连接,此时再访问 http://群辉IP:18080/install 才会看到管理员设置页面。这一步不要跳过,群辉图形界面显示的 running 状态有误导性。
4.3 首次访问设置管理员并接入模型供应商
安装页面打开后,Dify 要求设置管理员邮箱和密码。管理员邮箱是 super admin 账号,之后忘记密码需要进 postgres 容器手动重置。因此设置时一定选一个能长期记住的邮箱。
管理员设置完成后,进入控制台第一件事是「设置 → 模型供应商」添加大模型。Dify 支持 OpenAI、Azure OpenAI、Anthropic 等,但如果你没有云 API 账号,可以按第 6 章的方法把本地 Ollama 接进来。
# 在「设置 → 模型供应商」中添加 OpenAl-API-compatible 接口
# Base URL 填 http://localhost:11434/v1
# API Key 填任意值,模型名填已 pull 的模型
这里有个容易混淆的点:Dify 的模型分「系统推理模型」和「Agent 推理模型」。前者用于对话应用,后者用于工作流中的 Agent 节点。如果之后工作流节点报「模型未配置」,先看该节点选的是哪一类,别只看对话里的模型。
4.4 用 Dify 知识库建一个简单问答应用
模型接入后,最快验证可用性的方式是建一个知识库问答。进入「知识库 → 创建知识库」,上传一份 PDF 或 Markdown,Dify 自动分段并向量化。向量化过程会调用你在模型供应商配置的 Embedding 模型,如果默认的 text-embedding-ada-002 没有配置,知识库会卡在「处理中」。
# 创建空白应用后,在聊天助手提示词里引用知识库变量
# 启用知识库检索,发布后在预览窗口提问验证 RAG 链路
Dify 的聊天助手应用最多绑定多个知识库,默认检索模式是向量检索。在群辉这种内存有限设备上,我建议把召回数量从默认 3 调低到 2,减少向量计算给 CPU 的压力,响应会明显变快。
5. 群辉部署 Dify 避坑指南:权限、端口与内存的五条翻车记录
部署 Dify 过程中我在群辉上踩了不少坑,有些是 Dify 自己的问题,有些是群辉特有的。按「现象 → 原因 → 解决」记录五条,覆盖启动与运行两个阶段的高频故障。
5.1 启动阶段的三个必现坑
现象一:docker compose up -d 后,api 容器反复重启,日志里出现 Connection to postgres failed 。
原因:Container Manager 导入 compose 项目时不会自动读取同目录 .env,除非你在项目设置里明确指定环境变量来源。DB_HOST 和 DB_PASSWORD 为空,API 自然连不上。
解决:在 Container Manager 项目设置里指定 .env 文件绝对路径,或把数据库连接参数显式写进 docker-compose.yaml 的 environment。
现象二:web 容器起来后,访问 18080 端口返回 502 Bad Gateway。
原因:nginx 容器没有正确代理到前端容器,或群辉防火墙没放行 18080。群辉默认放行 80、443 等常见端口,非标准端口不在放行列表。
解决:控制面板 → 安全性 → 防火墙新增规则放行 18080,再查容器日志确认 nginx 是否成功连接 upstream。
现象三:安装页面走完,管理员账号却提示 Invalid email or password 。
原因:数据库迁移被中断过,accounts 表里已经有半份数据,管理员账号重复。
解决:进 db 容器清掉已有账号数据,再重新访问安装页面。
# 清除已有账号数据,注意该命令会删除所有账号
docker compose exec db psql -U postgres -d dify -c "TRUNCATE TABLE accounts CASCADE;"
执行后重新访问安装地址即可重新初始化。如果已经跑过真实数据,不要执行这条命令。
5.2 运行阶段的性能与队列坑
现象四:工作流跑一段时间,worker 容器内存飙升到容量上限,容器被杀,日志出现 Killed 。
原因:Dify worker 在无任务时会持续占住内存,接入本地模型后推理进程和 worker 进程争抢内存。8G 内存的群辉跑通没问题,但并发一高就触发 OOM Killer。
解决:修改 compose 文件,给 worker 加内存限制。
# docker-compose.yaml 的 worker 服务下追加
deploy:
resources:
limits:
memory: 1536M
设置后在 Container Manager 里重新部署项目,worker 内存被限制在 1.5G,不会拖垮群辉。
现象五:文档一直处于「处理中」状态,知识库无法检索。
原因:文档分段的 Embedding 计算由 worker 异步执行,.env 里 CELERY_WORKER_QUEUES 没包含 knowledge 队列,任务堆积在 redis 不被消费。
解决:确认 .env 中 CELERY_WORKER_QUEUES 包含 api 与 knowledge,重启 worker 容器。
# 确认 CELERY 队列配置后重启 worker
docker compose restart worker
重启后任务会被重新消费,文档状态从处理中变为可用。
6. 进阶:把本地模型接进 Dify 并配好反向代理
部署完成后,模型接入是决定实际可用性的关键一步。没有云 API 账号时,可以在群辉上用 Ollama 跑本地模型,把 DeepSeek、Qwen 这类开源模型挂到 Dify 的模型供应商。本章讲 Ollama 接入方式和群辉反向代理设置,让 Dify 在局域网内外的访问都稳定。
6.1 群辉上跑 Ollama:本地模型部署到 Dify
DSM 7.2 套件中心里有 Ollama 套件,安装后可以用命令行拉取模型,也可以直接在界面操作:
# 安装 Ollama 后拉取一个适合群辉的模型
ollama pull qwen3:4b
模型选择上,8G 内存的群辉建议用 4B 或 7B 的量化版,不要上 14B 以上,否则模型推理会占用超过一半内存,两个系统互相拖垮。Ollama 默认监听 11434,提供 OpenAI 兼容的 /v1 接口。
Dify 接入时进入「设置 → 模型供应商 → 添加模型」,选择 OpenAI-API-compatible,参数如下:
| 参数 | 填写值 | 说明 |
|---|---|---|
| Base URL | http://localhost:11434/v1 | 群辉本地地址 |
| API Key | ollama | 任意值,Ollama 不校验 |
| 模型名称 | qwen3:4b | 与 ollama pull 一致 |
| 模型类型 | LLM | 用于对话生成 |
容易忽略的一点:模型名含冒号在 Dify 某些版本会解析失败。解决办法是给模型打一个不带冒号的 tag:
# 给模型打一个不带冒号的 tag,Dify 里更容易识别
ollama cp qwen3:4b qwen3-4b
ollama rm qwen3:4b
ollama run qwen3-4b
6.2 群辉反向代理:把 Dify 暴露到局域网外
群辉控制面板自带反向代理,在「登录门户 → 反向代理」新建规则,源地址填 https 协议和端口,目的地址填 http://localhost:18080。这样通过群辉的 DDNS 域名能访问到 Dify,不用把 18080 直接暴露公网。
配置反向代理后,顺手在 .env 里改 CONSOLE_API_URL 和 APP_API_URL,把地址换成新的访问域名,否则 Dify 分享出去的链接仍指向内网地址,外网打开失败。我最初用反向代理时忘了改这两项,分享出去的聊天链接只有内网能点开,查了很久才发现 URL 没有同步。
从那以后,我每次在群辉上部署或升级 Dify,都会固定做一遍对照检查:端口是否冲突、SECRET_KEY 是否更换、.env 里的 URL 是否与反代地址一致、celery 队列是否完整。这套检查虽然简单,但能把大部分再现问题挡在部署之前。希望这篇群辉部署 Dify 的笔记能帮到你,尤其是第一次在 NAS 上跑 Docker 编排的人,少走一点弯路。
更多推荐

所有评论(0)