Dify 自托管用的是上游仓库自带的 compose 文件,不需要自己从零写一份。三条命令拉起来即可,最后一条会拉起十来个容器,首次要等镜像下载:
git clone https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env
docker compose up -d # 首次执行会拉镜像,视网速等几分钟
docker compose ps # 全部 Up 之后再访问
浏览器打开 http://你的服务器地址/install,设置管理员账户和密码,就进入控制台了。
Docker 引擎和 compose 插件是前提,docker compose version 能打印版本号才算装好。老教程里用的 docker-compose(带横杠)是另一个独立程序,和现在的 docker compose 子命令不通用,命令别混着抄。
这份 compose 文件很长,不建议直接改,改完下次 git pull 就冲突。正确做法是另建一个覆盖文件,只写你要改的部分,compose 会自动合并:
# 放在 dify/docker/ 目录下,文件名必须是 docker-compose.override.yaml
services:
nginx:
ports:
- "8088:80" # 把默认的 80 换成 8088,避免和别的站点冲突
restart: always
api:
environment:
# 给 API 容器挂上国内可达的接入地址,插件里就能少填一次
OPENAI_API_BASE: "https://xyuapi.top/v1"
# 提交流式请求时不缓冲,避免首字被延迟
HTTP_PROXY: ""
HTTPS_PROXY: ""
db:
volumes:
- ./volumes/db/data:/var/lib/postgresql/data
覆盖文件里只写要改的键,其余保持默认值。
| 配置项 | 作用 | 建议值 |
|---|---|---|
| 对外端口 | 控制台访问端口 | 避开 80 和 443,比如 8088 |
SECRET_KEY | 会话签名密钥 | 生成一串随机值替换掉默认的 |
DB_PASSWORD | 数据库密码 | 换成强密码 |
CONSOLE_API_URL | 控制台回调地址 | 填实际域名,不填会导致登录跳转异常 |
| 邮件与存储 | 若不用可留空 | 留空不影响模型接入 |
SECRET_KEY 一定要换。用默认值等于把会话签名钥匙公开写在仓库里,谁都算得出来。
docker compose logs -f api | tail -n 50 # 看到 worker 启动完成即可
docker compose ps # 每个容器都应该是 Up
容器显示 Up 但访问不了,先看 nginx 那个容器的端口映射有没有被占用。容器状态是 Restarting,基本是 .env 里有值填错了,去日志末尾找报错关键字。
登录后点右上角头像,进入「设置」,左侧选「模型供应商」。列表里找 OpenAI-API-compatible(有的版本显示为「OpenAI 兼容」),点添加模型,模型类型选 LLM。
如果插件市场打不开,也可以在服务器上装完再重启:Dify 的插件对网络比较敏感,国内机器访问插件市场偶尔会超时,多试一次或者配好镜像源即可,不影响已经装好的插件使用。
| 字段 | 填什么 | 说明 |
|---|---|---|
| 模型类型 | LLM | 对话模型都选这一项 |
| 模型名称 | deepseek-v3.2-thinking | 必须和模型列表里逐字一致 |
| API Key | 后台生成的令牌 | 首尾不能有空格 |
| API Base URL | https://xyuapi.top/v1 | 结尾 /v1 不能少 |
| 模型上下文长度 | 65536 | 按模型实际支持填写 |
| 最大 token 上限 | 8192 | 决定单次输出长度 |
| 支持 Vision | 看图才勾 | 勾了但模型不支持会报错 |
| 支持函数调用 | 要跑工具调用就勾 | 工作流里的工具节点依赖它 |
| 流式函数调用 | 一般勾上 | 影响工作流中工具调用的流式表现 |
填完点保存,再点「测试」按钮。绿灯说明四个字段全对;报错信息会明确说是认证问题还是模型问题,按提示改就行。
知识库要用到两种额外模型:文本嵌入模型负责把文档切片转成向量,重排模型负责对检索结果二次排序。嵌入模型同样走 OpenAI 兼容协议,填法和 LLM 一致,只是模型类型要选「Text Embedding」,并且模型名要用后台列表里实际提供的向量化型号,写错会报模型不存在。重排模型不是必需的,不配也能用,只是检索结果的相关性排序会差一些。
测试按钮只验证认证和模型存在性,不验证参数兼容性。稳妥做法是在「调试与预览」里发一条长一点的指令,比如让它输出八百字,看完整返回是否正常。短问答能和长输出正常是两回事,后者更容易暴露超时和 token 上限问题。
控制台点「创建应用」,选「聊天助手」,起个名字。进去之后右上角选模型,如果前面配置正确,下拉框里就能看到你刚添加的模型名。
系统提示词写清楚角色、输出格式和边界。比如「你是电商订单客服,只依据知识库内容回答,涉及退款金额一律让用户联系人工」。不写边界的助手会在用户追问时自己编答案,这类问题很难在测试阶段发现。
右上角点「发布」,然后到「访问 API」页面生成一个 Dify 自己的应用密钥。这个密钥用来调用 Dify 的接口,和你填进去的小鱼API 令牌是两个不同的东西,别混用。用 Dify 的接口做前端对接时,业务代码里完全不用出现模型相关的配置,改模型只在这个界面改。
「知识库」→「创建知识库」→ 上传文档 → 选分段方式 → 选嵌入模型 → 保存并处理。处理过程会调用嵌入模型,文档多的时候这一步耗时明显,按页面提示等待即可。
默认分段长度偏长,中文文档建议把最大分段长度调到 500 到 800 字,重叠保持在一成左右。段落被硬切断时上下文会缺一块,检索出来的片段读起来是断的,回答质量跟着下降。
召回数量建议先给 4 到 6 条,配合「向量检索」模式足够应付多数场景。开启「混合检索」并加重排模型,命中率会更好,代价是每次问答多花一次模型调用。召回条数调到十几条并不会让答案更准,反而引入噪音。
进入「工作流」应用,从左侧拖一个 LLM 节点出来,模型下拉框选你添加的那个。节点的提示词里用 {{变量名}} 引用上游输出,变量名在节点面板里能看到。
每个节点的输出都要在面板里定义成变量,下游节点才能引用。常见错误是上游节点输出了内容,但没有在「输出变量」里登记,下游引用时提示变量不存在。定义完建议点一下「运行」看每个节点的实际输出值。
代码节点跑的是沙箱里的 Python,适合做格式清洗、字段拼接、条件分支。不要在里面做网络请求,沙箱环境通常没有外网权限,会直接超时。
| 报错 | 真实原因 | 处理方式 |
|---|---|---|
| 401 认证失败 | 令牌有空格,或 Key 填到了别的供应商里 | 重新复制令牌,确认填在同一个供应商下 |
| 404 model not found | 模型名写错,或漏配了该模型 | 对照模型列表逐字核对 |
| 连接超时 | 容器访问不了外网,或被代理拦了 | 进容器里 curl 一次接入地址 |
| 保存后测不通 | 地址结尾多了斜杠或漏了 /v1 | 改成 https://xyuapi.top/v1 |
| 知识库处理失败 | 嵌入模型未配置或名字不对 | 单独测试嵌入模型连通性 |
| 流式输出卡住 | 反向代理开了缓冲 | 关掉代理的响应缓冲 |
界面报的连接超时,九成是容器网络问题而不是地址问题。直接进容器里测一次最直观:
docker compose exec api curl -s -o /dev/null -w '%{http_code}\n' https://xyuapi.top/v1/models
返回 401 说明网络通了、只是没带令牌,属于正常;返回 000 或超时,才是网络或 DNS 层面的问题。
Dify 的模型供应商配置里有超时项,思考型模型要把超时给足,否则长回答会在中途被掐断。前端看到的现象是文字打到一半停住。另外如果用 Nginx 之类的反向代理转发 Dify,记得关掉缓冲,否则流式输出会被攒成一整块再返回。
cd dify/docker
docker compose down
git pull # 拉取新版本
docker compose pull # 拉取新镜像
docker compose up -d
升级前先备份,这一步不能省。跨大版本升级时数据库结构会变,回滚没有备份就只能重装。
| 目录 | 存了什么 | 丢了会怎样 |
|---|---|---|
volumes/db | 应用、知识库、账户 | 全部数据丢失 |
volumes/app/storage | 上传的文档原文件 | 知识库要重新上传 |
volumes/plugin_daemon | 已装插件 | 插件要重装 |
docker/.env | 端口、密钥等配置 | 要重新配一遍 |
tar czf dify-backup-$(date +%Y%m%d).tar.gz volumes docker/.env
端口在 docker/.env 里改,不同版本的变量名略有差异,常见的是 EXPOSE_NGINX_PORT 这一项,改完 docker compose up -d 重新创建容器才生效。配了域名之后要同步改控制台的回调地址,否则登录后会跳到一个访问不了的地址上。
Dify 本身不产生模型费用,费用全部来自它背后调的模型接口,按调用次数计:
| 模型名 | 单价 | 适合放在哪个环节 |
|---|---|---|
gemini-2.5-pro | 0.031 元/次 | 意图识别、改写查询、轻量问答 |
deepseek-v3.2-thinking | 0.049 元/次 | 主对话、内容生成 |
claude-sonnet-4-5-thinking | 0.09 元/次 | 长文输出、复杂工作流 |
gpt-5.5 | 0.2 元/次 | 高难度推理环节 |
一次用户问答的实际花费等于链路上所有节点调用次数之和。开了意图分类、查询改写、重排、生成四个节点,一次问答就是四次调用。想压成本,优先砍掉收益低的节点,而不是换更便宜的模型——节点数量对成本的影响更直接。
Dify 的接入动作集中在两处:容器启动时把 .env 和覆盖文件里几个关键值改对,控制台里把一个 OpenAI 兼容供应商填准。之后所有的模型替换都在界面上完成,不用动代码。最容易卡住的地方是容器网络和模型名这两项,前者进容器里 curl 一次就能判断,后者对照模型列表逐字核对即可,两者都不需要重装环境。