# Dify ECS 部署完全指南 **文档版本**: v1.1 (修复致命配置错误) **创建时间**: 2025-12-13 **最后修订**: 2025-12-13 **适用范围**: AIclinicalresearch 平台 - Dify RAG 服务部署 **目标读者**: 运维工程师、后端开发工程师 **v1.1 更新日志**: - ✅ 修复:Redis 配置从 `localhost` 改为 `redis`(致命错误) - ✅ 新增:Swap 分区配置步骤(避免 OOM) - ✅ 修正:强调使用官方 docker-compose.yaml(包含 Nginx 网关) - ✅ 完善:故障排查章节,新增 Redis 连接失败和 CORS 错误的解决方案 --- ## 📋 文档目录 1. [为什么选择 ECS + Docker Compose](#为什么选择-ecs--docker-compose) 2. [部署架构图](#部署架构图) 3. [前置准备清单](#前置准备清单) 4. [ECS 服务器配置](#ecs-服务器配置) 5. [安装步骤](#安装步骤) 6. [配置说明](#配置说明) 7. [启动与验证](#启动与验证) 8. [监控与维护](#监控与维护) 9. [故障排查](#故障排查) 10. [注意事项与禁忌](#注意事项与禁忌) --- ## 为什么选择 ECS + Docker Compose ### ✅ 核心原因 #### 1. **数据合规与隐私(医疗行业红线)** ``` ❌ Dify 云服务 (SaaS):数据上传到第三方服务器 ✅ ECS 自建:数据 100% 在自己的阿里云账号内 ``` **影响**: - 三甲医院对科研数据出院有极严格管控 - 您可以对客户说:"数据就在我们的私有云服务器上,未来可部署在医院内网" - 符合 PRD 中的核心要求:"数据 100% 本地" #### 2. **商业模式适配(私有化部署能力)** ``` 您的商业模式(PRD): ├─ SaaS 版(多租户) ├─ 私有化部署(医院内网) └─ 单机版(Windows/Mac) ``` **关键**: - Dify 云服务无法私有化交付(医院内网无法连接公有云) - ECS + Docker Compose 可以直接打包成安装包,卖给医院做私有化部署 - 您现在的架构选型,是在为未来的商业模式铺路 #### 3. **技术迁移成本(避开"以后再切回来"的陷阱)** ``` RAG 系统迁移的复杂度: 1. 文档被切片 (Chunking) 2. 切片被向量化 (Embedding) 3. 存入向量数据库 (Weaviate/Qdrant) 4. Dify 云服务的向量数据很难无损导出 ``` **后果**:3 个月后想切回自建,可能面临所有知识库需要重新上传、重新解析、重新嵌入 #### 4. **网络性能与成本** | 路径对比 | Dify 云服务 | ECS 自建 | |---------|-----------|---------| | 网络路径 | SAE → 公网 → Dify → 公网 → SAE | SAE → 阿里云内网(VPC) → ECS | | 延时 | 100-300ms | 1-5ms | | 流量成本 | 消耗公网带宽 | 内网免费 | | 大文件处理 | 慢且不稳定 | 毫秒级响应 | **影响场景**: - PKB 模块的批量文档上传 - ASL 模块的深度阅读 (Deep Read) - 大量文档的向量化处理 --- ## 部署架构图 ``` ┌─────────────────────────────────────────────────────────────┐ │ 阿里云 VPC (同一区域) │ │ │ │ ┌─────────────┐ ┌─────────────────────────────┐ │ │ │ SAE (后端) │ ←内网→ │ ECS (Dify 服务) │ │ │ │ │ │ │ │ │ │ Node.js │ │ ┌─────────────────────┐ │ │ │ │ Backend │ │ │ Docker Compose: │ │ │ │ │ │ │ │ - Dify API │ │ │ │ │ │ │ │ - Weaviate (向量DB) │ │ │ │ │ │ │ │ - Nginx (反向代理) │ │ │ │ │ │ │ └─────────────────────┘ │ │ │ └─────────────┘ └─────────────────────────────┘ │ │ │ │ │ └──────────────→ RDS PostgreSQL 15 │ │ (共享数据库) │ └─────────────────────────────────────────────────────────────┘ ``` **关键点**: - SAE 和 ECS 必须在同一个 VPC(内网通信) - Dify 的 PostgreSQL 数据库可以和后端共用同一个 RDS 实例(不同 Schema) - 向量数据库 Weaviate 运行在 ECS 的 Docker 中 --- ## 前置准备清单 ### ✅ 必需资源 | 资源类型 | 配置建议 | 预估费用 | 用途 | |---------|---------|---------|-----| | **ECS 服务器** | 2核4G / 系统盘40GB / 数据盘100GB | ~200元/月 | 运行 Dify + Weaviate | | **RDS PostgreSQL** | 已有(共用) | 0元(增量) | Dify 元数据存储 | | **OSS 存储** | 已有(共用) | 按量计费 | 文档存储 | | **VPC 网络** | 已有(SAE所在VPC) | 0元 | 内网通信 | ### ✅ 软件准备 ```bash # 本地开发机器需要安装(用于推送镜像) - Docker Desktop - 阿里云 CLI(可选) # ECS 服务器需要安装(远程执行) - Docker Engine - Docker Compose ``` ### ✅ 账号与权限 - 阿里云账号(已有) - ECS 登录凭证(SSH密钥对) - Docker 镜像仓库(阿里云容器镜像服务 ACR) --- ## ECS 服务器配置 ### 步骤 1:购买 ECS 实例 1. **登录阿里云控制台** → **云服务器 ECS** → **创建实例** 2. **基础配置**: ``` 地域和可用区: 与 SAE 相同(如:华东1-杭州) 实例规格: ecs.t6-c1m2.large (2核4G) 镜像: Ubuntu 22.04 LTS 64位 存储: - 系统盘: ESSD云盘 40GB - 数据盘: ESSD云盘 100GB (挂载到 /data) ``` 3. **网络配置**: ``` 专有网络 VPC: 选择 SAE 所在的 VPC 安全组: 创建新安全组,配置入方向规则(⚠️ 安全红线): ✅ 允许 22/TCP 来源:您的办公室公网IP # SSH管理 ✅ 允许 80/TCP 来源:172.17.0.0/16 # Nginx(VPC内网访问) ❌ 拒绝 5000/TCP 来源:0.0.0.0/0 # Dify API禁止公网访问 ❌ 拒绝 6379/TCP 来源:0.0.0.0/0 # Redis禁止公网访问 ❌ 拒绝 8080/TCP 来源:0.0.0.0/0 # Weaviate禁止公网访问 ✅ 拒绝 所有 来源:0.0.0.0/0 # 默认拒绝 公网IP: 分配公网IPv4地址(用于SSH登录和镜像下载) ⚠️ 安全警告: - Dify API (5000)、Redis (6379)、Weaviate (8080) 绝对不能对公网开放 - 只允许VPC内网访问(172.17.0.0/16) - 端口绑定到 127.0.0.1(见docker-compose.yaml配置) ``` 4. **系统配置**: ``` 登录凭证: 使用密钥对(推荐)或密码 实例名称: dify-ecs-prod ``` ### 步骤 2:连接到 ECS ```bash # Windows 用户使用 PowerShell 或 Git Bash ssh -i "your-key.pem" root@ # 首次登录后,更新系统 apt update && apt upgrade -y ``` ### 步骤 3:挂载数据盘 ```bash # 查看磁盘 lsblk # 格式化数据盘(假设为 /dev/vdb) mkfs.ext4 /dev/vdb # 创建挂载点 mkdir -p /data # 挂载 mount /dev/vdb /data # 设置开机自动挂载 echo '/dev/vdb /data ext4 defaults 0 0' >> /etc/fstab # 验证 df -h ``` ### 步骤 4:配置 Swap 分区(关键!避免 OOM) **为什么必须配置 Swap?** - 您的 ECS 是 2核4G 内存 - Dify 全家桶(API+Worker+Web+Redis+Weaviate+Nginx)空载就需要 3GB+ - 有人上传大文件或进行向量检索时,极易发生 OOM(内存溢出)崩溃 - Swap 是内存的"救生圈",关键时刻能保证服务不崩溃 ```bash # 创建 4GB Swap 分区 fallocate -l 4G /swapfile # 设置权限(必须是 600,否则不安全) chmod 600 /swapfile # 格式化为 Swap mkswap /swapfile # 启用 Swap swapon /swapfile # 设置开机自动挂载 echo '/swapfile none swap sw 0 0' >> /etc/fstab # 验证 Swap 已启用 free -h # 应该看到 Swap 一行显示 4GB # 优化 Swap 使用策略(可选) # swappiness=10 表示尽量使用物理内存,只在必要时用 Swap echo 'vm.swappiness=10' >> /etc/sysctl.conf sysctl -p ``` ### 步骤 5:安装 Docker ```bash # 1. 卸载旧版本(如果有) apt remove docker docker-engine docker.io containerd runc # 2. 安装依赖 apt install -y ca-certificates curl gnupg lsb-release # 3. 添加 Docker 官方 GPG key mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 4. 设置 Docker 仓库 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null # 5. 安装 Docker Engine apt update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 6. 启动 Docker systemctl start docker systemctl enable docker # 7. 验证安装 docker --version docker compose version ``` ### 步骤 6:配置 Docker 镜像加速(可选但推荐) ```bash # 阿里云镜像加速器(登录阿里云控制台获取专属地址) mkdir -p /etc/docker cat > /etc/docker/daemon.json <.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker ``` --- ## 安装步骤 ### 步骤 1:准备 Dify 部署目录 ```bash # 在 ECS 上创建目录 mkdir -p /data/dify cd /data/dify # 克隆 Dify 官方仓库(使用稳定版本) git clone https://github.com/langgenius/dify.git cd dify # 切换到稳定版本(建议使用最新的 release 版本) git checkout tags/0.11.2 # 替换为最新稳定版本 # 进入 docker 目录 cd docker # ⚠️ 重要:使用官方的 docker-compose.yaml # 不要自己手写或大幅删减!官方配置包含了完整的服务(含 Nginx 网关) ``` ### 步骤 2:配置环境变量 ```bash # 复制配置模板 cp .env.example .env # 编辑配置文件 nano .env ``` **关键配置项**(必须修改): ```bash # ========= 核心配置 ========= # 安装模式:self-hosted(自建) INSTALL_MODE=self-hosted # 密钥(必须修改,使用强密码) SECRET_KEY=<生成一个随机字符串,至少32位> # 生成方法:openssl rand -base64 32 # ========= 数据库配置 ========= # 使用阿里云 RDS PostgreSQL DB_TYPE=postgres DB_HOST= DB_PORT=5432 DB_NAME=dify_prod DB_USERNAME=dify_user DB_PASSWORD= # 注意:需要在 RDS 中创建单独的数据库和用户 # 执行:CREATE DATABASE dify_prod; # CREATE USER dify_user WITH PASSWORD 'your-password'; # GRANT ALL PRIVILEGES ON DATABASE dify_prod TO dify_user; # ========= Redis 配置 ========= # Dify 必须使用 Redis(不能用 Postgres-Only) # ⚠️ 重要:在 Docker Compose 网络中,使用服务名而不是 localhost! REDIS_HOST=redis REDIS_PORT=6379 REDIS_PASSWORD= # ========= 向量数据库配置 ========= # 使用 Weaviate(Docker Compose 自动启动) VECTOR_STORE=weaviate WEAVIATE_ENDPOINT=http://weaviate:8080 WEAVIATE_API_KEY=<生成一个随机字符串> # ========= 存储配置 ========= # 使用阿里云 OSS(推荐) STORAGE_TYPE=aliyun-oss ALIYUN_OSS_BUCKET_NAME= ALIYUN_OSS_REGION=oss-cn-hangzhou ALIYUN_OSS_ACCESS_KEY_ID= ALIYUN_OSS_ACCESS_KEY_SECRET= # 或使用本地存储(不推荐) # STORAGE_TYPE=local # ========= LLM 配置 ========= # 默认 LLM 提供商(您可以在 Web UI 中添加多个) DEFAULT_LLM_PROVIDER=openai-api-compatible # DeepSeek API(示例) DEEPSEEK_API_KEY= DEEPSEEK_API_BASE=https://api.deepseek.com/v1 # ========= API 配置 ========= # API 服务地址(内网地址) API_URL=http://:5000 # Web 服务地址(如果需要访问 Dify Web UI) WEB_API_URL=http:// WEB_URL=http:// # ========= 日志配置 ========= LOG_LEVEL=INFO LOG_FILE=/data/logs/dify.log # ========= 其他配置 ========= # 时区 TZ=Asia/Shanghai # 是否开启 Debug DEBUG=false ``` ### 步骤 3:检查 Docker Compose 文件(建议使用官方配置) ```bash # ⚠️ 强烈建议:不要手写 docker-compose.yaml! # 直接使用官方文件,它包含了完整的架构(含 Nginx 网关) # 查看官方配置 cat docker-compose.yaml ``` **官方架构包含的服务**: ```yaml services: # 1. nginx - 入口网关(必需!) # 作用:路由请求到 API 和 Web,解决 CORS 问题 # /v1/* → API 服务 # /* → Web 服务 # 2. api - Dify API 服务 # 3. worker - 后台任务处理 # 4. web - Web 前端界面 # 5. redis - 缓存和任务队列(必需) # 6. weaviate - 向量数据库 # 7. sandbox - 代码解释器(可选,但建议保留) # 作用:如果在 Dify 中使用"代码解释器"功能 # 如果你删除了 nginx,会遇到: # - 前端访问 API 时 CORS 跨域错误 # - API 路由 404 错误 # 如果你删除了 sandbox,会遇到: # - "代码解释器"功能报错 ``` **仅需修改的部分**(如果有特殊需求): ```yaml # ⚠️ 安全配置:端口绑定到本地(防止公网访问) services: redis: ports: - "127.0.0.1:6379:6379" # ⚠️ 只监听本地,禁止公网访问 weaviate: ports: - "127.0.0.1:8080:8080" # ⚠️ 只监听本地,禁止公网访问 # 示例:如果需要外网访问 Web UI(通过Nginx) nginx: ports: - "80:80" # HTTP(允许VPC内网访问) - "443:443" # HTTPS(需要配置证书) ``` **⚠️ 安全红线:** ```yaml # ❌ 绝对禁止(会被攻击) services: redis: ports: - "6379:6379" # 全世界可访问,Redis无密码会被清空 weaviate: ports: - "8080:8080" # 向量数据可能被窃取 api: ports: - "5000:5000" # 黑客可绕过后端消耗LLM额度 # ✅ 正确做法:绑定到127.0.0.1 services: redis: ports: - "127.0.0.1:6379:6379" # 只能本机访问 ``` **❌ 错误做法**: ```yaml # 不要删减服务!尤其是 nginx services: api: ... worker: ... # ❌ 缺少 nginx(会导致前端无法访问 API) ``` **✅ 正确做法**: ```bash # 保持官方 docker-compose.yaml 不变 # 只修改 .env 环境变量 # 如果确实需要调整,只添加端口映射等无害配置 ``` ### 步骤 4:创建必需目录 ```bash mkdir -p /data/dify/storage mkdir -p /data/dify/logs mkdir -p /data/dify/redis mkdir -p /data/dify/weaviate # 设置权限 chmod -R 755 /data/dify ``` ### 步骤 5:初始化数据库 ```bash # 在 RDS 中创建 Dify 数据库(使用 psql 或 DBeaver) # 连接到 RDS psql -h -U postgres -d postgres # 执行 CREATE DATABASE dify_prod; CREATE USER dify_user WITH PASSWORD 'your-password'; GRANT ALL PRIVILEGES ON DATABASE dify_prod TO dify_user; \q ``` --- ## 启动与验证 ### 步骤 1:启动 Dify 服务 ```bash cd /data/dify/docker # 拉取镜像(首次运行) docker compose pull # 启动服务(后台运行) docker compose up -d # 查看日志 docker compose logs -f api # 等待服务启动(约30秒) ``` ### 步骤 2:验证服务状态 ```bash # 1. 检查容器状态 docker compose ps # 应该看到以下容器都是 Up 状态: # - dify-api # - dify-worker # - dify-web (如果启用) # - redis # - weaviate # 2. 检查 API 健康状态 curl http://localhost:5000/health # 期望返回: {"status": "healthy"} # 3. 检查 Weaviate 状态 curl http://localhost:8080/v1/meta # 期望返回: JSON 格式的元数据 ``` ### 步骤 3:测试内网连通性 ```bash # 在 SAE 后端服务中测试(或在本地通过 VPN 连接到 VPC) curl http://:5000/health # 如果返回 {"status": "healthy"},说明内网连通正常 ``` ### 步骤 4:初始化 Dify(首次部署) 1. **访问 Dify Web UI**(如果启用): ``` http:// ``` 2. **创建管理员账号**: - 邮箱:admin@your-domain.com - 密码: 3. **配置 LLM 提供商**: - 进入 "设置" → "模型提供商" - 添加 DeepSeek/Qwen 等 API Key ### 步骤 5:配置后端环境变量 在 SAE 后端服务的环境变量中添加: ```bash # Dify API 配置 DIFY_API_BASE=http://:5000 DIFY_API_KEY=<从 Dify Web UI 中获取> # 获取 API Key 的方法: # Dify Web UI → 设置 → API Keys → 创建新密钥 ``` --- ## 配置说明 ### 🔧 存储配置详解 #### 选项 1:阿里云 OSS(推荐) **优势**: - 无限扩展 - 高可用(99.9%) - 与 SAE 内网通信,速度快 **配置**: ```bash STORAGE_TYPE=aliyun-oss ALIYUN_OSS_BUCKET_NAME=your-bucket-name ALIYUN_OSS_REGION=oss-cn-hangzhou ALIYUN_OSS_ACCESS_KEY_ID= ALIYUN_OSS_ACCESS_KEY_SECRET= ``` **注意**: - OSS Bucket 必须和 ECS 在同一区域 - 建议使用内网 Endpoint(如:oss-cn-hangzhou-internal.aliyuncs.com) - 设置合理的生命周期规则(如:30天后转冷存储) #### 选项 2:本地存储(不推荐) **缺点**: - 磁盘空间有限 - 无法横向扩展 - 数据备份麻烦 **仅适用于**:测试环境或小规模部署 ### 🔧 数据库配置详解 #### Dify 数据库与后端数据库分离 ``` RDS PostgreSQL 实例 ├─ 数据库 1: clinical_research (后端主数据库) │ ├─ Schema: platform_schema │ ├─ Schema: asl_schema │ ├─ Schema: dc_schema │ └─ ... └─ 数据库 2: dify_prod (Dify 数据库) ├─ Schema: public └─ ... ``` **优势**: - 数据隔离(安全) - 独立备份策略 - 避免资源竞争 **连接池配置**: ```bash # Dify 的连接池较小(因为异步任务多) DB_MAX_CONNECTIONS=20 ``` ### 🔧 Redis 配置说明 **为什么 Dify 必须用 Redis?** - Dify 的任务队列依赖 Redis(Celery) - 短期缓存(如:API 限流) - 不能用 PostgreSQL 替代(与您的后端 Postgres-Only 架构不同) **关键配置(避免连接失败)**: ```bash # ⚠️ 致命错误警告: # 在 .env 中,REDIS_HOST 必须设置为服务名 "redis" # 不是 "localhost"! # ❌ 错误写法(会导致 API 无法启动) REDIS_HOST=localhost # ✅ 正确写法(Docker Compose 网络中使用服务名) REDIS_HOST=redis # 原理: # - 在 Docker Compose 中,容器之间通过服务名通信 # - localhost 指的是容器自己,不是 Redis 容器 # - redis 会被 Docker 网络解析为 Redis 容器的内网 IP ``` **安全加固**: ```bash # 1. 设置强密码 REDIS_PASSWORD=<至少16位随机字符串> # 2. 仅监听内网(docker-compose 中已配置) # Redis 容器不暴露端口到主机,仅在 Docker 网络内可访问 # 3. 禁用危险命令(可选) # 在 docker-compose.yaml 中修改 Redis 启动命令 command: > redis-server --requirepass ${REDIS_PASSWORD} --rename-command CONFIG "" --rename-command FLUSHALL "" --rename-command FLUSHDB "" ``` --- ## 监控与维护 ### 📊 日志管理 #### 1. 查看实时日志 ```bash cd /data/dify/docker # 查看所有服务日志 docker compose logs -f # 查看特定服务日志 docker compose logs -f api docker compose logs -f worker ``` #### 2. 日志文件位置 ``` /data/dify/logs/ ├─ api.log # API 服务日志 ├─ worker.log # Worker 日志 └─ error.log # 错误日志 ``` #### 3. 日志轮转配置 ```bash # 安装 logrotate(Ubuntu 默认已安装) apt install logrotate # 创建配置文件 cat > /etc/logrotate.d/dify < -U postgres -d dify_prod -c " SELECT count(*) FROM pg_stat_activity WHERE datname = 'dify_prod'; " ``` #### 3. Redis 监控 ```bash # 连接到 Redis 容器 docker exec -it dify-redis redis-cli -a # 查看信息 INFO INFO memory INFO stats ``` ### 🔄 定期维护任务 #### 每周任务 ```bash # 1. 清理 Docker 日志 truncate -s 0 $(docker inspect --format='{{.LogPath}}' dify-api) truncate -s 0 $(docker inspect --format='{{.LogPath}}' dify-worker) # 2. 清理无用的 Docker 资源 docker system prune -a --volumes -f ``` #### 每月任务 ```bash # 1. 数据库 VACUUM(在低峰期执行) psql -h -U dify_user -d dify_prod -c "VACUUM ANALYZE;" # 2. 检查磁盘碎片 e2fsck -f /dev/vdb # 3. 备份配置文件 tar -czf /backup/dify-config-$(date +%Y%m%d).tar.gz /data/dify/docker/.env ``` --- ## 故障排查 ### 🔥 常见问题 #### 问题 1:API 容器无法启动 - Redis 连接失败(高频错误) **症状**: ```bash docker compose ps # 显示 dify-api 状态为 Exit 1 或不断重启 docker compose logs api # 显示错误: # redis.exceptions.ConnectionError: Error connecting to localhost:6379 # 或 # Cannot connect to Redis at localhost:6379 ``` **根本原因**: ```bash # ❌ .env 文件中配置错误 REDIS_HOST=localhost # 这是错的! ``` **解决方法**: ```bash # 1. 编辑 .env 文件 nano /data/dify/docker/.env # 2. 修改 REDIS_HOST REDIS_HOST=redis # ✅ 改为服务名 # 3. 重启服务 docker compose down docker compose up -d # 4. 验证 docker compose logs api | grep -i redis # 应该看到:Successfully connected to Redis ``` #### 问题 2:前端访问 API 报 CORS 错误 **症状**: ``` 浏览器控制台报错: Access to XMLHttpRequest at 'http://xxx/v1/xxx' from origin 'http://yyy' has been blocked by CORS policy ``` **根本原因**: - 缺少 Nginx 网关服务 - 或者 Nginx 配置错误 **解决方法**: ```bash # 1. 确认 Nginx 容器是否运行 docker compose ps | grep nginx # 2. 如果没有 Nginx,说明你删除了官方配置 # 解决方案:重新克隆官方仓库,使用完整的 docker-compose.yaml cd /data/dify rm -rf dify git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env # 重新配置 .env(参考前文) docker compose up -d ``` #### 问题 3:容器无法启动 - 数据库连接失败 **症状**: ```bash docker compose logs api # 显示错误: # could not connect to server: Connection refused ``` **排查步骤**: ```bash # 1. 检查 RDS 白名单 # 阿里云控制台 → RDS → 数据安全性 → 白名单设置 # 确认添加了 ECS 的内网 IP # 2. 检查 .env 配置 DB_HOST= # 不是公网地址! DB_PORT=5432 DB_NAME=dify_prod DB_USERNAME=dify_user DB_PASSWORD=<正确的密码> # 3. 测试连接(在 ECS 上) telnet 5432 # 如果连接失败,检查安全组和白名单 ``` #### 问题 4:服务运行一段时间后崩溃(OOM 内存溢出) **症状**: ```bash dmesg | grep -i kill # 显示:Out of memory: Killed process xxx (dify-api) docker compose ps # 容器不断重启 ``` **根本原因**: - 2核4G 内存不足 - 没有配置 Swap 分区 **解决方法**: ```bash # 1. 立即配置 Swap(如果之前没配置) fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile none swap sw 0 0' >> /etc/fstab # 2. 验证 Swap 已启用 free -h # 3. 重启服务 docker compose restart # 4. 长期方案:升级 ECS 到 4核8G ``` #### 问题 2:API 返回 500 错误 **排查步骤**: ```bash # 1. 查看 API 日志 docker compose logs -f api | grep ERROR # 2. 检查数据库连接 docker exec -it dify-api sh # 在容器内执行 python -c " import psycopg2 conn = psycopg2.connect( host='', database='dify_prod', user='dify_user', password='' ) print('Connection OK') " ``` #### 问题 3:向量搜索失败 **排查步骤**: ```bash # 1. 检查 Weaviate 状态 curl http://localhost:8080/v1/meta # 2. 查看 Weaviate 日志 docker compose logs weaviate # 3. 重建索引(最后手段) # 在 Dify Web UI 中:设置 → 数据集 → 重新索引 ``` #### 问题 4:内网连接失败(SAE 无法访问 ECS) **排查步骤**: ```bash # 1. 检查安全组规则 # 阿里云控制台 → ECS → 安全组 → 确认开放 5000 端口给 SAE 所在网段 # 2. 测试连通性(在 SAE 容器内执行) telnet 5000 # 3. 检查防火墙(在 ECS 上执行) ufw status # 如果启用了防火墙,添加规则: ufw allow from to any port 5000 ``` ### 🔄 重启服务 ```bash # 重启所有服务 cd /data/dify/docker docker compose restart # 重启单个服务 docker compose restart api # 完全重建(如果修改了 docker-compose.yaml) docker compose down docker compose up -d ``` --- ## 注意事项与禁忌 ### ✅ 最佳实践 1. **定期备份** ```bash # 每天自动备份(添加到 crontab) 0 2 * * * pg_dump -h -U dify_user dify_prod | gzip > /backup/dify_$(date +\%Y\%m\%d).sql.gz ``` 2. **监控磁盘空间** ```bash # 设置告警(当 /data 使用率 > 80% 时通知) # 可使用阿里云云监控服务 ``` 3. **使用内网域名** ```bash # 为 ECS 设置内网域名(便于维护) # 在 SAE 中配置 DIFY_API_BASE=http://dify.internal:5000 # 而不是写死 IP ``` 4. **版本锁定** ```bash # docker-compose.yaml 中使用具体版本号,不要用 latest image: langgenius/dify-api:0.11.2 # ✅ 推荐 # image: langgenius/dify-api:latest # ❌ 禁止(可能导致不兼容) ``` ### ❌ 绝对禁止 1. **禁止在 .env 中使用 REDIS_HOST=localhost** ```bash # ❌ 致命错误(会导致服务启动失败) REDIS_HOST=localhost # ✅ 正确配置(在 Docker Compose 中使用服务名) REDIS_HOST=redis ``` 2. **禁止删减官方 docker-compose.yaml 的核心服务** ```bash # ❌ 危险操作(会导致功能异常) # - 删除 nginx → 前端 CORS 错误 # - 删除 worker → 异步任务失败 # - 删除 sandbox → 代码解释器功能失效 # ✅ 正确做法 # 使用官方完整配置,仅修改 .env 环境变量 ``` 3. **禁止在 2核4G 的 ECS 上不配置 Swap** ```bash # ❌ 危险(极易 OOM 崩溃) # 没有 Swap,内存用尽后服务直接被 Kill # ✅ 必须配置 Swap fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile ``` 4. **禁止在生产环境使用 DEBUG=true** ```bash # 会暴露敏感信息(如:API Key、数据库密码) DEBUG=false # ✅ ``` 5. **禁止使用弱密码** ```bash # 必须使用强密码(至少16位,包含大小写、数字、特殊字符) SECRET_KEY=$(openssl rand -base64 32) REDIS_PASSWORD=$(openssl rand -base64 24) WEAVIATE_API_KEY=$(openssl rand -base64 24) ``` 6. **禁止暴露 Redis 和 Weaviate 端口到公网** ```bash # 官方配置默认不暴露这些端口,不要自己添加 # ❌ 危险配置 services: redis: ports: - "6379:6379" # 会被攻击! # ✅ 正确做法:仅在 Docker 网络内访问 ``` 7. **禁止直接修改数据库** ```bash # 不要手动修改 Dify 数据库的表结构或数据 # 必须通过 Dify API 或 Web UI 操作 ``` 8. **禁止在 ECS 上运行其他无关服务** ```bash # 这台 ECS 专门用于 Dify,不要部署其他应用 # 避免资源竞争和安全风险 ``` ### ⚠️ 重要提醒 1. **数据主权** - 所有向量数据和文档都存储在您的 ECS 和 OSS 上 - 定期检查数据备份的完整性 2. **成本控制** - ECS 按量付费 vs 包年包月(根据实际情况选择) - 监控 OSS 存储量和流量(避免超出预算) 3. **升级策略** ```bash # 升级 Dify 版本前的步骤: # 1. 备份数据库 # 2. 在测试环境验证 # 3. 选择业务低峰期升级 # 4. 做好回滚准备 ``` 4. **私有化部署路径** ``` 当前架构 → 直接复制到客户环境 ├─ 导出 docker-compose.yaml ├─ 导出 .env(敏感信息替换) ├─ 打包为安装脚本(一键部署) └─ 提供《私有化部署手册》 ``` --- ## 📚 附录 ### A. 生成强密码的方法 ```bash # 方法 1: 使用 openssl openssl rand -base64 32 # 方法 2: 使用 pwgen pwgen -s 32 1 # 方法 3: 使用 Python python3 -c "import secrets; print(secrets.token_urlsafe(32))" ``` ### B. Dify API 常用端点 ```bash # 健康检查 GET http://:5000/health # 创建数据集 POST http://:5000/v1/datasets Headers: Authorization: Bearer Body: {"name": "test-dataset"} # 上传文档 POST http://:5000/v1/datasets/{dataset_id}/documents Headers: Authorization: Bearer Body: (multipart/form-data) # 语义检索 POST http://:5000/v1/datasets/{dataset_id}/retrieve Headers: Authorization: Bearer Body: {"query": "xxx", "top_k": 5} ``` ### C. 相关文档链接 - [Dify 官方文档](https://docs.dify.ai/) - [Docker Compose 文档](https://docs.docker.com/compose/) - [Weaviate 文档](https://weaviate.io/developers/weaviate) - [阿里云 ECS 文档](https://help.aliyun.com/product/25365.html) - [阿里云 OSS 文档](https://help.aliyun.com/product/31815.html) --- **文档维护**: - 如有问题或建议,请联系技术负责人 - 最后更新:2025-12-13 - 下次审查:2025-03-13