🎏:你只管努力,剩下的交给时间
🏠 :小破站
从零搭建 Dify AI 平台:一次跌宕起伏的部署之旅
-
- 前言
- 服务器环境
- [Dify 架构解析](#Dify 架构解析)
-
- 各容器的职责
-
- [1. dify-nginx:流量指挥官](#1. dify-nginx:流量指挥官)
- [2. dify-api & dify-worker:业务大脑](#2. dify-api & dify-worker:业务大脑)
- [3. Redis:三重身份](#3. Redis:三重身份)
- [4. PostgreSQL:数据仓库](#4. PostgreSQL:数据仓库)
- [5. Weaviate:向量大脑](#5. Weaviate:向量大脑)
- [6. plugin-daemon:扩展引擎](#6. plugin-daemon:扩展引擎)
- [7. sandbox & ssrf_proxy:安全卫士](#7. sandbox & ssrf_proxy:安全卫士)
- 目录结构设计
- 部署过程:踩坑实录
-
- 坑1:镜像版本不存在
- 坑2:路径硬编码问题
- 坑3:网络配置的大坑
- [坑4:端口 80 冲突](#坑4:端口 80 冲突)
- [坑5:Nginx 配置错误](#坑5:Nginx 配置错误)
- [坑6:plugin-daemon 的连环坑](#坑6:plugin-daemon 的连环坑)
- 坑7:数据库未初始化
- 坑8:日志文件爆满
-
- 策略1:限制容器日志
- [策略2:Nginx 日志轮转](#策略2:Nginx 日志轮转)
- [策略3:定时清理 Docker](#策略3:定时清理 Docker)
- 完整配置文件
- 启动流程
- [NPM 反向代理配置](#NPM 反向代理配置)
-
- [Details 标签页](#Details 标签页)
- [SSL 标签页](#SSL 标签页)
- [Advanced 标签页](#Advanced 标签页)
- 请求流程全景图
- 故障排查
-
- [1. 容器不停重启](#1. 容器不停重启)
- [2. 页面访问 502](#2. 页面访问 502)
- [3. Plugin 相关 400 错误](#3. Plugin 相关 400 错误)
- [4. 数据库相关错误](#4. 数据库相关错误)
- 性能优化建议
-
- [1. PostgreSQL 调优(16GB 内存)](#1. PostgreSQL 调优(16GB 内存))
- [2. Redis 优化](#2. Redis 优化)
- [3. API Worker 调优](#3. API Worker 调优)
- 监控与维护
- 安全加固
-
- [1. 修改默认端口](#1. 修改默认端口)
- [2. 防火墙规则](#2. 防火墙规则)
- [3. 定期更新](#3. 定期更新)
- 成果展示
- 总结与经验
-
- [1. 充分理解架构](#1. 充分理解架构)
- [2. 环境变量是魔鬼细节](#2. 环境变量是魔鬼细节)
- [3. 日志是最好的老师](#3. 日志是最好的老师)
- [4. 官方文档可能过时](#4. 官方文档可能过时)
- [5. 40GB 磁盘真的够呛](#5. 40GB 磁盘真的够呛)
- [6. 备份是必须的](#6. 备份是必须的)
- 写在最后
本文记录了在 CentOS Stream 9 服务器上使用 Docker Compose 部署 Dify 的完整过程,包括踩过的所有坑和解决方案。
前言
最近公司想搭建一套私有化的 AI 应用平台,选来选去最终选了 Dify。官方文档看起来很简单,docker-compose up -d 一把梭,但实际部署时却遇到了一堆问题。这篇文章不会告诉你"五分钟快速部署"的美梦,而是分享真实的部署过程和那些让人抓狂的错误。
服务器环境
- 系统:CentOS Stream 9(香港节点)
- 配置:16 核 CPU + 16GB 内存 + 20Mbps 带宽
- 硬盘:40GB 系统盘(没错,就这么小!)
- Docker:29.0.1
- Docker Compose:v2.40.3

Dify 架构解析
在开始部署前,先理解 Dify 是怎么工作的。它不是一个单体应用,而是由多个容器协同工作:

各容器的职责
1. dify-nginx:流量指挥官
这是 Dify 内部的反向代理,负责把请求分发到正确的服务:
/→ dify-web(前端页面)/api→ dify-api(API 接口)/console/api→ dify-api(控制台 API)/v1→ dify-api(应用 API)
关键点:它不直接暴露到外网,而是通过 Nginx Proxy Manager(NPM)访问。这样做的好处是 SSL 证书、域名都由 NPM 统一管理。
2. dify-api & dify-worker:业务大脑
这两个容器用的是同一个镜像 langgenius/dify-api,但通过环境变量 MODE 区分角色:
- dify-api (
MODE=api):处理 HTTP 请求,负责用户交互 - dify-worker (
MODE=worker):处理异步任务,比如训练模型、处理文件
它们通过 Redis 的消息队列通信:

3. Redis:三重身份
Redis 在 Dify 中扮演三个角色:
- 缓存:Session、用户权限等热数据
- 消息队列:Celery 任务队列(DB 0、1、2)
- 分布式锁:防止并发操作冲突
配置中使用了不同的 DB 隔离:
yaml
REDIS_DB: 0 # Session 存储
CELERY_BROKER_URL: redis://:密码@redis:6379/1 # 任务队列
CELERY_RESULT_BACKEND: redis://:密码@redis:6379/2 # 结果存储
4. PostgreSQL:数据仓库
Dify 用了两个数据库:
dify:主业务数据(用户、应用、对话历史等)dify_plugin:插件系统专用数据库
这个设计很巧妙,插件系统完全隔离,不会影响主业务。
5. Weaviate:向量大脑
这是个向量数据库,负责存储文档的 Embedding(向量表示)。当你问 AI 问题时,流程是这样的:

6. plugin-daemon:扩展引擎
这是 Dify 0.4+ 版本引入的插件系统守护进程。它做两件事:
- 管理插件:安装、卸载、版本控制
- 运行插件:提供隔离的 Python 运行环境
它有两个端口:
5002:HTTP API(给 dify-api 调用)5003:远程调试端口(gnet 协议)
7. sandbox & ssrf_proxy:安全卫士
- sandbox:代码沙箱,用户可以在工作流中运行 Python 代码,但被严格隔离
- ssrf_proxy:SSRF 防护代理,防止代码访问内网敏感服务

目录结构设计
部署前先规划好目录,这能避免很多麻烦:
bash
/acowbo/docker-compose/dify/
├── docker-compose.yml # 核心编排文件
├── .env # 环境变量(包含密钥!)
├── nginx/ # Nginx 配置
│ ├── nginx.conf # 主配置
│ ├── proxy.conf # 代理设置
│ └── conf.d/
│ └── dify.conf # 路由规则
├── volumes/ # 持久化数据
│ ├── app/storage/ # 用户上传文件
│ ├── postgres/data/ # 数据库数据
│ ├── redis/data/ # Redis 持久化
│ ├── weaviate/data/ # 向量数据
│ ├── plugin-daemon/ # 插件文件
│ ├── sandbox/dependencies/ # 沙箱依赖
│ └── nginx/logs/ # 访问日志
├── cleanup-docker.sh # 清理脚本
├── logrotate-dify # 日志轮转
└── init.sh # 初始化脚本

部署过程:踩坑实录
坑1:镜像版本不存在
官方文档可能会过时。我一开始配置的是:
yaml
image: langgenius/dify-api:1.10.0
启动时报错:Error response from daemon: manifest for langgenius/dify-api:1.10.0 not found
去 Docker Hub 一看,根本没有 1.10.0 这个 tag!
解决方案 :用 latest 标签,或者去 Docker Hub 确认版本。
yaml
image: langgenius/dify-api:latest
坑2:路径硬编码问题
我参考的文档里路径是 /opt/dify/dify-build,但我实际部署在 /acowbo/docker-compose/dify。结果 logrotate-dify 文件里写死了路径:
bash
/opt/dify/dify-build/volumes/nginx/logs/*.log {
# 配置...
}
导致日志轮转找不到文件。
经验教训:
- docker-compose.yml 里尽量用相对路径(
./volumes) - 系统级配置文件要手动改成实际路径
- 部署前用
grep -r "你的路径"全局检查
坑3:网络配置的大坑
我想让 Dify 和 Nginx Proxy Manager(NPM)共享网络 acowbo_network,一开始这样配置:
yaml
networks:
acowbo_network:
name: acowbo_network
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
启动时警告:network with name acowbo_network exists but was not created for project "dify"
原因是 NPM 已经创建了这个网络,Dify 不能重复创建。
正确做法:
yaml
networks:
acowbo_network:
external: true # 使用已存在的外部网络
坑4:端口 80 冲突
启动时报错:Bind for 0.0.0.0:80 failed: port is already allocated
因为 NPM 已经占用了 80 端口!其实 Dify 的 Nginx 根本不需要暴露端口,通过容器名访问就行。
解决方案:
yaml
nginx:
# ports: # 注释掉,不暴露端口
# - "80:80"
NPM 中配置反向代理:
Domain: dify.acowbo.com
Forward to: http://dify-nginx:80 # 用容器名
流程图:

坑5:Nginx 配置错误
我把 map 指令放在了 proxy.conf 里:
nginx
# proxy.conf(错误位置)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
启动报错:nginx: [emerg] "map" directive is not allowed here
map 指令只能放在 http 块,而 proxy.conf 是被 include 到 server 块的。
正确做法:
nginx
# nginx.conf
http {
# map 指令必须在这里
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include /etc/nginx/proxy.conf;
include /etc/nginx/conf.d/*.conf;
}
坑6:plugin-daemon 的连环坑
这是最折磨人的部分,花了几个小时调试。
问题1:容器反复重启
日志显示:[PANIC]Invalid configuration: plugin remote installing host is empty
缺少环境变量。查官方文档和源码后,发现需要配置:
yaml
environment:
SERVER_KEY: ${SECRET_KEY} # 认证密钥
SERVER_PORT: 5002 # HTTP API 端口
PLUGIN_REMOTE_INSTALLING_HOST: 0.0.0.0 # 调试服务地址
PLUGIN_REMOTE_INSTALLING_PORT: 5003 # 调试端口
PLUGIN_WORKING_PATH: /app/storage/cwd # 工作目录
# 数据库配置
DB_DATABASE: dify_plugin # 注意:不是 dify!
问题2:端口配置混乱
plugin-daemon 有两个服务:
- GIN HTTP 服务(端口 5002):给 dify-api 调用的 REST API
- gnet 远程调试服务(端口 5003):供开发者远程调试插件
我一开始把两个端口搞混了,导致 API 连接失败。
关键配置:
yaml
# plugin-daemon
environment:
SERVER_PORT: 5002 # GIN HTTP 端口
PLUGIN_REMOTE_INSTALLING_PORT: 5003 # gnet 调试端口
# dify-api
environment:
PLUGIN_DAEMON_URL: http://plugin-daemon:5002 # 连接 HTTP 端口
日志验证:
[gnet] Launching gnet with 8 event-loops, listening on: tcp://0.0.0.0:5003
[GIN] 200 | GET "/health/check" # HTTP 服务在 5002
问题3:环境变量名错误
这个最坑!我配置了 PLUGIN_DAEMON_ENDPOINT,但 Dify 代码里认的是 PLUGIN_DAEMON_URL!
测试:
bash
docker exec dify-api python -c \
"from configs import dify_config; print(dify_config.PLUGIN_DAEMON_ENDPOINT)"
# 报错:AttributeError: 'DifyConfig' object has no attribute 'PLUGIN_DAEMON_ENDPOINT'
# Did you mean: 'PLUGIN_DAEMON_TIMEOUT'?
正确的环境变量:
bash
# .env 文件
PLUGIN_DAEMON_URL=http://plugin-daemon:5002 # 不是 ENDPOINT!
PLUGIN_DAEMON_KEY=你的密钥
问题4:认证失败(401)
配置都对了,但请求返回 401 Unauthorized。
测试发现认证方式不对:
bash
# 错误(Bearer Token)
curl -H "Authorization: Bearer 密钥" http://plugin-daemon:5002/plugin/xxx
# 401 Unauthorized
# 正确(X-Api-Key)
curl -H "X-Api-Key: 密钥" http://plugin-daemon:5002/plugin/xxx
# 200 OK
查看源码确认了认证方式:
python
# api/core/plugin/impl/base.py
prepared_headers["X-Api-Key"] = dify_config.PLUGIN_DAEMON_KEY
坑7:数据库未初始化
第一次访问页面,所有 /console/api/ 接口都返回 400:
sqlalchemy.exc.ProgrammingError: relation "dify_setups" does not exist
原因是数据库表还没创建。
解决方案:
bash
# 运行数据库迁移
docker exec dify-api flask db upgrade
# 重启服务
docker compose restart api worker
然后访问 https://你的域名/install 完成初始化,创建管理员账号。
坑8:日志文件爆满
40GB 系统盘很容易被日志撑爆!必须做日志管理。
策略1:限制容器日志
yaml
services:
api:
logging:
driver: "json-file"
options:
max-size: "50m" # 单文件最大 50MB
max-file: "2" # 保留 2 个文件
compress: "true" # 压缩旧日志
策略2:Nginx 日志轮转
bash
# /etc/logrotate.d/dify
/acowbo/docker-compose/dify/volumes/nginx/logs/*.log {
daily # 每天轮转
rotate 7 # 保留 7 天
maxsize 100M # 超过 100M 强制轮转
compress # 压缩
delaycompress # 延迟一天压缩
missingok # 文件不存在不报错
notifempty # 空文件不轮转
postrotate
docker exec dify-nginx nginx -s reopen
endscript
}
部署:
bash
sudo cp logrotate-dify /etc/logrotate.d/dify
sudo chmod 644 /etc/logrotate.d/dify
sudo logrotate -d /etc/logrotate.d/dify # 测试
策略3:定时清理 Docker
bash
# cleanup-docker.sh
docker system prune -f --volumes --filter "until=168h" # 删除 7 天前的数据
docker image prune -a -f --filter "until=168h"
# crontab
0 3 * * 0 /acowbo/docker-compose/dify/cleanup-docker.sh
完整配置文件
docker-compose.yml(核心部分)
yaml
services:
api:
image: langgenius/dify-api:latest
container_name: dify-api
restart: always
environment:
TZ: Asia/Hong_Kong # 时区
MODE: api
SECRET_KEY: ${SECRET_KEY}
# 数据库
DB_USERNAME: ${DB_USERNAME:-postgres}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: postgres
DB_PORT: 5432
DB_DATABASE: dify
# Redis
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD}
# 插件配置(关键!)
PLUGIN_ENABLED: true
PLUGIN_DAEMON_URL: http://plugin-daemon:5002 # 注意是 URL 不是 ENDPOINT
PLUGIN_DAEMON_KEY: ${SECRET_KEY}
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- acowbo_network
depends_on:
- postgres
- redis
plugin-daemon:
image: langgenius/dify-plugin-daemon:0.4.1-local
container_name: dify-plugin-daemon
restart: always
environment:
TZ: Asia/Hong_Kong
# 服务配置
SERVER_PORT: 5002 # HTTP API
SERVER_KEY: ${SECRET_KEY}
# 调试配置
PLUGIN_REMOTE_INSTALLING_HOST: 0.0.0.0
PLUGIN_REMOTE_INSTALLING_PORT: 5003 # gnet 调试端口
PLUGIN_WORKING_PATH: /app/storage/cwd
# 数据库(独立库)
DB_USERNAME: ${DB_USERNAME:-postgres}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: postgres
DB_PORT: 5432
DB_DATABASE: dify_plugin # 注意:不是 dify
# Redis
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD}
volumes:
- ./volumes/plugin-daemon:/app/storage
networks:
- acowbo_network
depends_on:
- postgres
networks:
acowbo_network:
external: true # 与 NPM 共享网络
.env(记得改密钥!)
bash
# ========================================
# 密钥配置(必须修改!)
# ========================================
SECRET_KEY=<生成随机密钥>
DB_PASSWORD=<生成随机密码>
REDIS_PASSWORD=<生成随机密码>
WEAVIATE_API_KEY=<生成随机密钥>
# ========================================
# 域名配置
# ========================================
CONSOLE_WEB_URL=https://your_domain.com
CONSOLE_API_URL=https://your_domain.com
APP_WEB_URL=https://your_domain.com
# ========================================
# 插件配置(关键!)
# ========================================
PLUGIN_ENABLED=true
PLUGIN_DAEMON_URL=http://plugin-daemon:5002 # 不是 ENDPOINT
PLUGIN_DAEMON_KEY=${SECRET_KEY}
# ========================================
# 数据库性能优化(16GB 内存)
# ========================================
POSTGRES_SHARED_BUFFERS=2GB
POSTGRES_EFFECTIVE_CACHE_SIZE=8GB
REDIS_MAXMEMORY=512mb
生成随机密钥:
bash
# SECRET_KEY(64 字符)
openssl rand -base64 48
# 密码(32 字符)
openssl rand -base64 24
启动流程
详细步骤
bash
# 1. 创建目录并上传文件
mkdir -p /acowbo/docker-compose/dify
cd /acowbo/docker-compose/dify
# 上传 docker-compose.yml, .env, nginx/ 等文件
# 2. 生成密钥并修改 .env
vi .env
# 修改所有密钥和域名
# 3. 创建数据目录
./init.sh # 或手动创建 volumes/ 下的目录
# 4. 确保 Docker 网络存在(如果用外部网络)
docker network create acowbo_network || true
# 5. 启动服务
docker compose up -d

bash
# 6. 查看状态
docker compose ps

bash
# 7. 初始化数据库(第一次部署)
docker exec dify-api flask db upgrade
# 8. 重启确保配置生效
docker compose restart api worker
# 9. 访问初始化页面
https://你的域名/install
NPM 反向代理配置
Details 标签页
Domain Names: dify.acowbo.com
Scheme: http
Forward Hostname/IP: dify-nginx
Forward Port: 80
☑ Cache Assets
☑ Block Common Exploits
☑ Websockets Support ← 必须勾选!
SSL 标签页
SSL Certificate: Request a new SSL Certificate
☑ Force SSL
☑ HTTP/2 Support
☑ HSTS Enabled
Email: your@email.com
☑ I Agree to the Let's Encrypt Terms of Service
Advanced 标签页
nginx
# AI 响应可能较慢,增加超时
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
# 支持文件上传
client_max_body_size 100M;
# 传递真实 IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
请求流程全景图

故障排查
1. 容器不停重启
bash
# 查看日志
docker logs 容器名 --tail 100
# 常见原因:
# - 环境变量缺失
# - 数据库连接失败
# - 端口被占用
# - 配置文件语法错误
2. 页面访问 502
bash
# 检查容器状态
docker compose ps
# 检查网络连通性
docker exec dify-nginx curl http://api:5001/health
docker exec dify-nginx curl http://web:3000/
# 检查 NPM 到 dify-nginx
docker exec npm容器名 curl http://dify-nginx/health
3. Plugin 相关 400 错误
这是最常见的错误,检查清单:
bash
# 1. 确认环境变量名正确
docker exec dify-api env | grep PLUGIN
# 应该看到:
# PLUGIN_DAEMON_URL=http://plugin-daemon:5002 (不是 ENDPOINT)
# PLUGIN_DAEMON_KEY=...
# 2. 测试连接
docker exec dify-api curl -H "X-Api-Key: 你的密钥" \
http://plugin-daemon:5002/health/check
# 3. 查看 plugin-daemon 日志
docker logs dify-plugin-daemon --tail 50
# 4. 确认数据库存在
docker exec dify-postgres psql -U postgres -l | grep plugin
4. 数据库相关错误
bash
# relation "xxx" does not exist
# → 运行迁移
docker exec dify-api flask db upgrade
# password authentication failed
# → 检查 .env 中的 DB_PASSWORD
# could not connect to server
# → 检查 postgres 容器是否启动
docker compose ps postgres
性能优化建议
1. PostgreSQL 调优(16GB 内存)
bash
# .env
POSTGRES_SHARED_BUFFERS=2GB # 共享缓冲区
POSTGRES_EFFECTIVE_CACHE_SIZE=8GB # 系统缓存
POSTGRES_WORK_MEM=16MB # 排序/JOIN 内存
POSTGRES_MAINTENANCE_WORK_MEM=512MB # 维护操作内存
POSTGRES_MAX_CONNECTIONS=200 # 最大连接数
2. Redis 优化
bash
REDIS_MAXMEMORY=512mb # 最大内存
REDIS_MAXMEMORY_POLICY=allkeys-lru # 淘汰策略
3. API Worker 调优
bash
# Celery 并发
CELERY_WORKER_CLASS=gevent # 使用协程
CELERY_MAX_WORKERS=8 # 根据 CPU 核心数
监控与维护
日志查看技巧
bash
# 实时查看所有容器日志
docker compose logs -f
# 只看特定服务
docker compose logs -f api worker
# 查看最近 100 行
docker logs dify-api --tail 100
# 查看最近 5 分钟
docker logs dify-api --since 5m
# 过滤错误
docker logs dify-api 2>&1 | grep -i error
备份策略
bash
#!/bin/bash
# backup.sh
BACKUP_DIR="/backup/dify-$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 备份数据库
docker exec dify-postgres pg_dump -U postgres dify > $BACKUP_DIR/dify.sql
docker exec dify-postgres pg_dump -U postgres dify_plugin > $BACKUP_DIR/dify_plugin.sql
# 备份向量数据
docker exec dify-weaviate curl -X POST http://localhost:8080/v1/backups/filesystem \
-H "Content-Type: application/json" \
-d '{"id":"backup-'$(date +%Y%m%d)'"}'
# 备份上传文件
tar -czf $BACKUP_DIR/storage.tar.gz volumes/app/storage/
# 删除 7 天前的备份
find /backup -name "dify-*" -mtime +7 -exec rm -rf {} \;
定时任务:
bash
# crontab -e
0 2 * * * /acowbo/docker-compose/dify/backup.sh
磁盘空间监控
40GB 系统盘必须时刻盯着:
bash
# 查看磁盘使用
df -h
# 查看 Docker 占用
docker system df
# 查看各目录大小
du -sh volumes/*
# 查看日志大小
du -sh volumes/nginx/logs/
du -sh /var/lib/docker/containers/*/
告警脚本:
bash
#!/bin/bash
# disk-alert.sh
USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $USAGE -gt 80 ]; then
echo "磁盘使用率: $USAGE% - 告警!" | mail -s "Dify 磁盘告警" admin@example.com
# 清理 Docker
docker system prune -f
fi
安全加固
1. 修改默认端口
yaml
# NPM 管理端口别用 81
ports:
- "10811:81" # 用随机高端口
2. 防火墙规则
bash
# 只开放必要端口
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=10811/tcp # NPM 管理
firewall-cmd --reload
# 限制 NPM 管理端口访问
firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="你的IP"
port port="10811" protocol="tcp"
accept'
3. 定期更新
bash
# 拉取最新镜像
docker compose pull
# 重启服务
docker compose up -d
# 清理旧镜像
docker image prune -a -f --filter "until=168h"
成果展示
部署完成后的界面:

访问地址:https://your_domain.com
功能验证清单:
- ✅ 用户注册/登录
- ✅ 创建应用
- ✅ 上传文档训练
- ✅ 对话测试
- ✅ 插件安装
- ✅ Workflow 编排
- ✅ API 调用
总结与经验
这次部署从下午 1 点折腾到晚上 9 点,踩了无数坑。总结几点经验:
1. 充分理解架构
不要一上来就 docker-compose up,先搞清楚每个容器的作用和依赖关系。Dify 的微服务架构并不复杂,但容器间的交互需要弄明白。
2. 环境变量是魔鬼细节
- 变量名要精确(
PLUGIN_DAEMON_URLvsPLUGIN_DAEMON_ENDPOINT) - 密钥要一致(API 的 KEY 和 plugin-daemon 的 SERVER_KEY)
- 别忘了非标准端口(plugin-daemon 的 5002 和 5003)
3. 日志是最好的老师
遇到问题别慌,看日志:
bash
docker logs 容器名 --tail 100 --follow
90% 的问题日志里都有答案。
4. 官方文档可能过时
尤其是 plugin-daemon 这种新功能,文档更新不及时。遇到问题要:
- 看官方 GitHub Issues
- 查看源码(Python/Golang)
- 用
docker exec进容器探索
5. 40GB 磁盘真的够呛
建议:
- 挂载对象存储(OSS)存用户文件
- 日志必须轮转
- 定期清理 Docker 缓存
6. 备份是必须的
数据库没备份,睡觉都不踏实。至少做到:
- 每天自动备份数据库
- 每周全量备份
- 备份文件异地存储
写在最后
Dify 是个很棒的 AI 应用平台,但部署确实不算"开箱即用"。希望这篇文章能帮到想要自建的朋友,少踩点坑。
如果你也遇到了部署问题,欢迎交流讨论。记住:日志是你最好的朋友,耐心是你最大的武器。
参考资料:
