作业15:Dify 隔离部署 · 容器依赖图 · Worker 故障 Runbook · 备份清单(动手 + Cursor)
作业目标:用官方 Docker Compose 在隔离环境起一套 Dify 测试栈;画出容器/服务依赖图(标数据卷与数据库);模拟停 Worker,观察 Redis 队列与用户现象并写入 Runbook;用 Cursor 生成「Dify 备份清单」(DB + 存储 + 向量)。
验收标准:
1. 隔离实例可访问(端口与生产错开,如
:8085)2. 能画出/讲解依赖图:nginx → api/web/worker → postgres/redis/weaviate + 卷挂载
3. 停 Worker 后:知识库索引卡住、队列 LLEN 上升;恢复 Worker 后队列消化
4. 备份清单 MD/JSON 已生成,能说出 3 类必備数据(DB、文件存储、向量)
环境:207 生产 Dify 占
:80— 本作业禁止动生产 worker;只在dify-hw15或本机独立目录实验。HTML:
docs/html_cursor/作业15_Dify隔离部署与Worker故障Runbook_cursor.html
脚本:
scripts_cursor/作业15_Dify隔离与备份/隔离 env 片段:
patches_cursor/作业15_隔离环境/hw15.env.example结果:
data/homework15/Runbook 单页:
作业15_值班Runbook_Worker宕机_cursor.md备份清单:
作业15_Dify备份清单_cursor.md(可由脚本生成)
目录
- 做完长什么样
- 学习路线
- Part A · 隔离环境部署
- Part B · 容器依赖图(卷 + 库)
- Part C · 停 Worker 实验
- Part D · Cursor 任务:备份清单
- 附录:RAGFlow 对照(可选)
- 完整程序
- 验收清单
做完长什么样
| 项 | 值 |
|---|---|
| 隔离访问 | http://192.168.110.207:8085(示例,以 .env 为准) |
| Compose 项目名 | dify-hw15 |
| 向量库 | Weaviate(volumes/weaviate) |
| 主库 | PostgreSQL(volumes/db/data) |
| 队列观察 | hw15_02_观察Redis队列.py --label after_worker_stop |
| 备份产物 | data/homework15/dify_backup_checklist_YYYYMMDD.md |
学习路线
A 独立目录 + 改端口 → docker compose up(勿碰生产 :80)
B 对照依赖图认服务:谁连 PG / Redis / Weaviate / storage 卷
C 上传测试文档 → 停 worker → 看 UI + Redis 队列 → 写 Runbook
D 跑 hw15_01 生成备份清单;对照 PG + storage + 向量三件套Part A · 隔离环境部署
A1. 原则(必读)
| 规则 | 说明 |
|---|---|
| 独立目录 | 如 /opt/dify-hw15,自带 volumes/,勿软链生产数据 |
| 独立端口 | EXPOSE_NGINX_PORT=8085(生产已用 80) |
| 独立项目名 | COMPOSE_PROJECT_NAME=dify-hw15,避免容器名冲突 |
| 只停隔离 worker | 生产 docker compose stop worker 禁止在本作业执行 |
A2. 207 上快速起栈(示例)
# 在 207 执行
sudo mkdir -p /opt/dify-hw15
sudo rsync -a --exclude volumes /opt/workbuddy/ /opt/dify-hw15/
cd /opt/dify-hw15
# 合并隔离 env(见 patches_cursor/作业15_隔离环境/hw15.env.example)
cat /opt/workbuddy/patches_cursor/作业15_隔离环境/hw15.env.example >> .env
# 若生产已占用 80,确认 .env 里 EXPOSE_NGINX_PORT=8085
grep EXPOSE_NGINX_PORT .env
docker compose --project-name dify-hw15 up -d
docker compose --project-name dify-hw15 ps
curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8085/首次安装按官方流程初始化管理员;向量库 Weaviate 需 profile weaviate(.env 中 COMPOSE_PROFILES=weaviate,postgresql)。
A3. 从零克隆官方(无 207 快照时)
git clone https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env
# 改 EXPOSE_NGINX_PORT=8085,COMPOSE_PROFILES=weaviate,postgresql
docker compose up -dA4. 健康检查
docker compose --project-name dify-hw15 ps
docker compose --project-name dify-hw15 logs worker --tail 20
curl -sS http://127.0.0.1:8085/health 2>/dev/null || curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8085/Part B · 容器依赖图(卷 + 库)
B1. 核心服务依赖(本仓库 compose,Weaviate + PostgreSQL)
flowchart TB
subgraph ingress["入口"]
NGINX["nginx :80→8085"]
WEB["web 前端"]
end
subgraph app["应用层"]
API["api MODE=api"]
WS["api_websocket profile"]
WORKER["worker MODE=worker Celery"]
BEAT["worker_beat 定时"]
PLUGIN["plugin_daemon"]
AGENT["agent_backend"]
SBX["sandbox / local_sandbox"]
SSRF["ssrf_proxy"]
end
subgraph data["数据层"]
PG[("db_postgres\nvolumes/db/data")]
REDIS[("redis\nvolumes/redis/data\nCelery broker")]
WV[("weaviate host网络\nvolumes/weaviate")]
RELAY["weaviate_relay"]
end
subgraph files["文件卷"]
STOR["volumes/app/storage\n上传文件/知识库原文"]
PLG["volumes/plugin_daemon"]
end
USER((用户浏览器)) --> NGINX
NGINX --> WEB
NGINX --> API
NGINX --> WS
API --> PG
API --> REDIS
API --> WV
API --> RELAY
RELAY --> WV
API --> STOR
API --> PLUGIN
API --> AGENT
API --> SBX
SBX --> SSRF
WORKER --> PG
WORKER --> REDIS
WORKER --> WV
WORKER --> RELAY
WORKER --> STOR
WORKER --> PLUGIN
BEAT --> PG
BEAT --> REDIS
PLUGIN --> PG
PLUGIN --> PLG
AGENT --> REDIS
INIT["init_permissions"] -.-> STOR
API -.depends.-> INIT
WORKER -.depends.-> INITB2. 数据卷与数据库对照表
| 挂载路径 | 服务 | 内容 | 丢失影响 |
|---|---|---|---|
volumes/db/data | db_postgres | 用户、应用、数据集元数据、对话索引状态 | 致命 |
volumes/app/storage | api, worker | 上传文件、本地 STORAGE 对象 | 致命(与 PG 记录成对) |
volumes/weaviate | weaviate | 向量 embedding | 检索不可用(需重建索引) |
volumes/redis/data | redis | 缓存 + Celery 队列 | 队列可重建;缓存可冷启动 |
volumes/plugin_daemon | plugin_daemon | 插件包与运行时 | 插件需重装 |
volumes/sandbox/* | sandbox | 沙箱依赖 | 可重装 |
B3. 请求 vs 异步边界
| 路径 | 同步(api 直接处理) | 异步(worker + Redis 队列) |
|---|---|---|
| 简单对话(已索引知识库) | 大多可完成 | Langfuse ops_trace 可能滞后 |
| 知识库上传/重建索引 | API 接受任务 | dataset 队列,worker 写向量 |
| 邮件邀请 | API 入队 | mail 队列 |
| 删除应用/数据集 | API 入队 | app_deletion 队列 |
作业 3 已说明:Agent Trace 上报走 Celery → 停 worker 时 Langfuse 延迟或缺失。
Part C · 停 Worker 实验
C1. 实验前准备
- 登录隔离 Dify(
:8085) - 创建空知识库,上传一份小 PDF/TXT(触发
dataset队列) - 记录 baseline 队列:
# 若 Redis 未映射宿主机端口,在容器内执行:
docker compose --project-name dify-hw15 exec redis redis-cli -a difyai123456 LLEN dataset
# 或使用脚本(需 Redis 可达;隔离环境可临时映射 6380:6379)
python scripts_cursor/作业15_Dify隔离与备份/hw15_02_观察Redis队列.py \
--redis-port 6379 --label baselineC2. 停 Worker(仅隔离项目)
cd /opt/dify-hw15
docker compose --project-name dify-hw15 stop worker
docker compose --project-name dify-hw15 ps workerC3. 观察现象(填表)
| 观察点 | Worker 正常 | Worker 停止 |
|---|---|---|
| 控制台知识库文档状态 | 索引完成 / 可用 | 长时间「索引中」 |
redis LLEN dataset | 接近 0 | 上升或维持 >0 |
| 对已索引文档的问答 | 正常 | 通常仍可答(向量已在) |
| 新上传文档 | eventually 可用 | 不可用 |
| Langfuse Trace(若已接) | 数十秒内出现 | 延迟或一直无(ops_trace) |
API /health | 200 | 仍可能 200(易误判「系统正常」) |
再上传一份文件,重复观察 LLEN dataset。
python scripts_cursor/作业15_Dify隔离与备份/hw15_02_观察Redis队列.py \
--label after_worker_stopC4. 恢复
docker compose --project-name dify-hw15 start worker
docker compose --project-name dify-hw15 logs worker -f --tail 50
# 等待 dataset LLEN 降为 0,UI 索引变绿C5. Runbook
完整值班一页见:作业15_值班Runbook_Worker宕机_cursor.md(打印贴运维群)。
Part D · Cursor 任务:备份清单
D1. 提示词(可复制到 Cursor)
阅读本仓库 docker-compose.yaml 与 volumes 目录结构,
生成 Python 脚本 hw15_01_备份清单.py:
- 列出 DB、app/storage、向量库(weaviate/milvus/pgvector)、plugin_daemon、redis
- 标注是否必備、备份方式、恢复注意事项
- 输出 Markdown + JSON 到 data/homework15/
- 支持 --dify-root --vector-store --db-type 参数D2. 运行
python scripts_cursor/作业15_Dify隔离与备份/hw15_01_备份清单.py
python scripts_cursor/作业15_Dify隔离与备份/hw15_01_备份清单.py --dify-root /opt/dify-hw15D3. 人工必背三件套
- PostgreSQL(或 MySQL) — 元数据与索引状态
volumes/app/storage(或 S3 桶) — 原始文件- 向量卷 —
volumes/weaviate(或 milvus/pgvector)
详情见 作业15_Dify备份清单_cursor.md 或脚本生成物。
附录:RAGFlow 对照(可选)
本作业以 Dify 为主(与 207 现网一致)。若选 RAGFlow 官方 compose,依赖图大致为:
flowchart LR UI[RAGFlow Web] --> API[RAGFlow Server] API --> MYSQL[(MySQL)] API --> ES[(Elasticsearch)] API --> MINIO[(MinIO 对象)] API --> REDIS2[(Redis)] TASK[Task Executor] --> MYSQL TASK --> ES TASK --> MINIO TASK --> REDIS2
停 Task Executor 等效于 Dify 停 Worker:文档解析/embedding 队列堆积,UI 显示处理中。端口请与 Dify :80、:8085 错开。
完整程序
| 文件 | 作用 |
|---|---|
hw15_01_备份清单.py | 生成 DB+存储+向量备份清单 |
hw15_02_观察Redis队列.py | Worker 实验前后队列快照 |
patches_cursor/作业15_隔离环境/hw15.env.example | 隔离端口与 profile |
验收清单
- [ ] 隔离 Dify 在
:8085(或自定端口)可打开,与生产:80并存 - [ ] 能口述或展示依赖图:nginx、api、worker、postgres、redis、weaviate、storage 卷
- [ ] 在隔离环境执行
stop worker,知识库索引卡住且dataset队列 LLEN 上升 - [ ]
start worker后队列消化、索引恢复 - [ ] 已生成
dify_backup_checklist_*.md,说出 DB + storage + 向量必備项 - [ ] Runbook 单页已读:
作业15_值班Runbook_Worker宕机_cursor.md - [ ] 未在生产环境 stop worker
相关文档
- 安装:
Dify_Qwen安装配置手册_cursor - Weaviate 中继:
Dify_专题六_weaviate中继_cursor - Langfuse 异步 trace:
作业3_追踪Agent工具调用验收_cursor - 企业排错 SOP:
企业AI助手排错SOP_培训与赋能_cursor