Dify本地部署全流程:Docker Compose启动、排错、备份与升级

发布时间:2026/10/24 7:41:38
Dify本地部署全流程:Docker Compose启动、排错、备份与升级 简介Dify 官方项目完整源码安装包取自 GitHub面向希望本地部署、体验或二次开发 Dify 的开发者与运维人员可解决官方安装包获取与项目主体文件缺失的问题也适合作为软件或插件类项目研究其工程组织。压缩包共 2000 个文件约 20.25MB以 Python 后端代码、JSON/YAML 配置、CSS/JS 前端资源为主另含 Markdown 文档、Shell 脚本、HTML 模板、SQL 初始化语句及 XML/TXT 辅助文件基本覆盖运行、配置、界面与部署所需组件。已有 2916 人学习或下载在 Dify 实践群体中具备一定参考价值。解压后可沿目录查看核心模块、配置项与文档说明用于搭建本地环境、梳理前后端协作方式或作为插件扩展与二次开发的起点。1. 一套跑在自己机器上的 LLM 应用平台先把「安装包」这三个字说清楚很多人搜 Dify 官方安装包期望拿到一个双击就能装完的 exe 或者 setup 向导结果在 GitHub 下载下来解压一看是一堆 YAML 和.env.example当场愣住。这是最常见的预期错位官方发布的是源码归档真正的“安装”动作发生在docker/目录里靠 Docker Compose 拉起一整套容器。想清楚这一点后面所有步骤才顺。适合谁想把知识库问答、Agent 编排、模型接入握在自己手里、又不想从零写后端的团队也适合只想在本地跑一套环境做验证的开发者。反过来如果你的机器只有 2G 内存、或者公司网络完全禁止容器出网这套东西会让你很痛苦先别急。2. 拆开压缩包docker 目录里到底躺着什么2.1 Releases 页面下到的东西与你想的不一样在仓库的 Releases 页面通常能拿到两类东西一类是自动生成的源码归档Source code 的 zip 和 tar.gz另一类是随版本附带的说明或校验文件。绝大多数人需要的就是源码归档。解压之后你会得到一个以版本号命名的顶层目录里面是后端、前端、SDK 等多个子目录部署入口只有一个docker/。我把这个目录里真正影响部署的文件列一下方便你判断哪些能动、哪些别碰路径作用是否建议修改docker/.env.example全部环境变量的样板键名以此为准只读复制成.env再改docker/docker-compose.yaml服务编排、镜像标签、卷挂载、依赖关系一般不直接改用 override 文件docker/nginx/反向代理配置、端口、上传大小、超时按需改docker/ssrf_proxy/出站代理配置限制容器能访问哪些地址内网环境必看docker/volumes/数据卷宿主机挂载点数据库、文件、向量库都在这不要手删这里有个血泪经验docker-compose.yaml和.env.example是成对演进的新版本经常新增服务、新增必填变量。你如果只把docker/目录覆盖成新的.env还是半年前那份docker compose up大概率会报某个变量为空导致容器直接退出。正确做法永远是先 diff 一遍.env.example把新增的键补进自己的.env再动镜像。另外提醒一句不要试图从包里找.sql初始化脚本手动建库。表结构由 api 容器启动时执行的迁移流程负责你手工建反而会打架。2.2 十个容器各管一段谁在前、谁在后一套标准编排起来大致是这些角色不同版本可能增减但职责划分基本稳定nginx唯一对外的入口把/console/api、/api、/v1等路径分发给后端其余静态资源给前端。web前端服务负责界面渲染本身不碰数据库。api核心后端处理控制台接口、应用运行时接口、对外 Service API。worker异步任务进程知识库文档解析、分段、向量化、网页抓取都在这里跑。它和 api 共用同一份代码和同一个数据库。dbPostgreSQL存应用配置、会话、消息、账号等结构化数据。redis缓存加消息队列worker 从这里取任务。weaviate默认向量库存文档分段的向量。sandbox代码执行与工具调用的隔离环境。plugin_daemon插件运行时模型供应商、工具插件都跑在它下面。ssrf_proxy出站代理沙箱和部分外部请求经由它出去。调用链理解清楚排查就快一半浏览器 → nginx → web/apiapi 读写 db、redis、向量库上传文档后 api 把任务丢进 redisworker 消费并把向量写进 weaviateapi 调插件时走 plugin_daemon沙箱执行外部请求时走 ssrf_proxy。哪一环断现象都不一样。2.3 为什么官方只认 Docker Compose 这条路有人问能不能pip install一把梭。理论上后端是 Python 的前端是 Node 的你自己拼也能拼出来但代价是Python 版本要卡准、前端要单独构建、PostgreSQL 和 Redis 得自己装、向量库还得挑一个装、迁移脚本要手动跑、worker 要单独起进程并保证和 api 用同一份配置。这套东西手工对齐熟手也要折腾大半天而且一旦出问题版本组合的锅很难甩清。Compose 的价值就在于把这堆版本约束固化成一份文件镜像标签写死、卷挂载写死、启动顺序用depends_on加健康检查兜住。代价是资源占用——一套全起来空跑也要吃掉两三个 G 内存向量库和数据库是大头。所以 2 核 4G 是能跑的下限4 核 8G 才是能安心用的配置如果你还要在上面跑本地 embedding 模型另算。3. 从解压到第一次登录一套能复现的启动流程3.1 起容器之前的三项检查别急着up先花两分钟把下面三件事确认掉能省掉后面一半的报错。第一是 Docker 与 Compose 插件版本。现在用的是docker compose空格插件形态不是老的docker-compose横杠。跑一下确认# 确认 docker 引擎与 compose 插件都在 docker version --format {{.Server.Version}} docker compose version第二是内核参数。向量库这类组件对内存映射区有要求vm.max_map_count太小会在启动阶段直接崩日志里是一串看不懂的映射失败# 查看当前值低于 262144 建议调高 sysctl vm.max_map_count # 临时生效重启失效永久生效写到 /etc/sysctl.conf sudo sysctl -w vm.max_map_count262144第三是端口和磁盘。默认会占用宿主机 80 端口做入口很多机器上这个端口已经被别的 Web 服务占了磁盘方面镜像加卷留 20G 起步比较稳知识库一多volumes/app/storage涨得比你想的快。# 看 80/443 有没有被占 ss -lntp | grep -E :(80|443)\s # 看根分区余量单位 G df -h /提示如果 80 端口被占又不想动别的服务别去改 compose 里的端口映射直接改.env里的对外端口变量即可下一节会说。3.2 .env 里真正必须改的六个键把样板复制成实际配置然后只改必要的部分。全部键都改一遍是给自己挖坑尤其是那些你并不理解的开关。cd docker cp .env.example .env # 生成一个强随机密钥作为会话与凭据加密的根 openssl rand -base64 42拿到随机串之后按下面几类逐个落实密钥类SECRET_KEY必须换且一旦定下来就不能再改。它参与登录态签名和模型供应商凭据的加密存储中途换掉已存的 API Key 全部解不开用户也得重新登录。这是我最想强调的一条。数据库与缓存口令DB_PASSWORD、REDIS_PASSWORD换成强口令。这两个值要和 compose 里传给 db、redis 容器的变量保持一致通常样板里已经用变量引用串好了你只改这一处就行。对外地址类CONSOLE_API_URL、CONSOLE_WEB_URL、SERVICE_API_URL、APP_WEB_URL、FILES_URL。本机自测可以留空走相对路径一旦挂到域名后面这几个必须填成浏览器能访问到的完整地址否则上传的文件预览打不开、插件回调找不到入口。端口类对外暴露端口那个变量改成你实际空闲的端口比如 8080。向量库选择VECTOR_STORE决定用哪个向量库。默认值和 compose 里默认启用的服务是配套的改之前先确认对应服务已经启用别只改一半。迁移开关MIGRATION_ENABLED保持开启让 api 容器启动时自动建表升级。一个常被忽略的点.env里的值如果包含$、#、空格记得加引号否则会被解析截断报错信息完全指不到这一行。3.3 启动、看日志与健康校验配置齐了就起。第一次会拉不少镜像耐心等别在中途 CtrlC半拉状态最容易留下坏卷。# 后台启动全部服务首次会拉镜像 docker compose up -d # 看容器状态重点看有没有 Restarting 或 Exited docker compose ps # 跟踪后端日志迁移进度和报错都在这 docker compose logs -f apidocker compose ps里如果某个容器反复重启先别急着重启全部直接看那个容器的日志docker compose logs --tail200 服务名绝大多数原因就写在最后几十行。api 日志里看到迁移执行完成、Gunicorn 正常监听之后做一次入口连通性验证# 换成你实际配置的端口 curl -I http://127.0.0.1:8080/ # 探一下后端接口是否可达返回 200 或 401 都算通 curl -s -o /dev/null -w %{http_code}\n http://127.0.0.1:8080/console/api/setup返回 200 说明系统还没初始化管理员浏览器打开对应地址就会跳到初始化页面设置邮箱和密码即可。设完之后这个接口会变成 401 或 403属于正常。到这一步一套环境就算立住了。4. 参数落到生产数据库、反代与沙箱的调法4.1 数据库与向量库卷、连接与内存先说卷。所有持久化数据都落在docker/volumes/下面按服务分目录数据库一个、文件存储一个、向量库一个、插件一个。这个设计的含义很直接——容器可以随便删这个目录不能删。备份的本质就是备份这个目录加一份数据库逻辑导出后面一章会展开。再说连接。api 和 worker 是两个进程各自维护自己的数据库连接池默认池大小是按小规模场景设的。并发一上来最先出问题的往往不是 CPU 而是连接数现象是接口偶发超时、日志里出现连接获取等待。我一般会把池大小按(api 副本数 worker 并发数) × 单进程连接数估一遍再和 PostgreSQL 的max_connections对一下别让应用侧的池加起来超过数据库上限。# 看数据库实际连接数逼近上限就该调了 docker compose exec db psql -U postgres -c \ select count(*), state from pg_stat_activity group by state;向量库的选型是个绕不开的决策给你一张对照表按规模挑方案部署成本适用规模备注weaviate低默认自带中小知识库单机开箱即用内存占用中等qdrant低中小知识库过滤查询友好配置简单pgvector最低复用现有库小规模、不想多一个组件和业务库同生共死扩容受限milvus高依赖多大规模、需要独立扩缩容组件多小机器别碰换向量库不是改一个变量就完事compose 里对应服务要启用连接地址和凭据要填对而且切换之后旧向量不会自动迁移已有知识库得重新索引。这一点在动手前必须算进时间成本。4.2 Nginx 反代与上传413 和超时的源头上传大小限制是最容易踩的一处因为它在三个地方各有一份改漏一个就白改。第一处是反向代理层。请求体超过它的限制会直接被挡回 413压根到不了后端。第二处是后端的上传限制变量样板里通常有几个单文件大小、批量文件数、图片大小。第三处是前端自己的校验提示。三处的数值要从大到小或者相等让代理层放行、后端做最终判定否则要么用户看到一个没头没尾的 413要么后端明明允许却被代理拦了。# docker/nginx/conf.d/ 下对应站点配置里的关键几行 client_max_body_size 100m; # 要和后端上传上限对齐或略大 proxy_read_timeout 3600s; # 长任务、流式输出场景必须放大 proxy_send_timeout 3600s; proxy_buffering off; # 流式响应不要缓冲否则前端一卡一卡的proxy_buffering off这条尤其值得说。知识库问答和 Agent 走的是流式返回开着缓冲会出现“等半天然后一大段字突然全出来”的观感很多人以为是模型慢其实是代理在攒数据。另一个常被忘的是超时。文档解析、批量索引这类操作耗时长如果反向代理读超时只有默认的几十秒前端会频繁看到网关超时但后端任务其实还在跑用户重试一次就重复索引一遍白白烧算力。4.3 沙箱与出站代码执行和插件下载的边界沙箱这块的设计意图是双重的既隔离用户代码也限制它能访问哪些地址防止被拿来探测内网。沙箱的出站请求会走那个代理容器代理的配置文件里是一份允许清单。如果你的应用需要调用内网自建的模型服务、或者访问某个内部 API请求会被拦下来现象是代码节点执行失败但日志里没有明显的异常堆栈。处理方式是往代理配置里加放行规则而不是图省事把代理关掉。关掉等于把内网暴露面直接摊开这笔账不划算。同理如果宿主环境本身不允许容器出网那所有依赖外网的能力都得提前规划别等上线才发现。插件守护进程是另一个出网点。安装插件本质是去插件源拉包网络不通就是安装一直转圈然后失败。离线环境的常见做法是在有网机器上把插件包下下来再导入到目标环境而不是硬开网络。另外那个“内网 API 地址”变量填的必须是容器网络内可达的地址填成127.0.0.1是最典型的错——在容器里127.0.0.1 指的是容器自己不是宿主机。5. 排查实录五个从「起不来」到「跑不稳」的坑5.1 启动阶段端口、密钥、数据库版本坑一docker compose up直接报端口被占用整套起不来。现象是 nginx 容器不断重启日志里明确写着绑定 80 失败。原因是宿主机上已经有别的 Web 服务占着 80而编排文件里端口映射是写死的默认值。解决办法是改.env里的对外暴露端口然后docker compose up -d重建别去动docker-compose.yaml里的映射段——动了以后升级时容易被覆盖掉问题重现一次。改完用ss -lntp复核一眼。坑二中途改过SECRET_KEY模型供应商全部报凭据无效。现象是之前配好的模型突然调不通界面上提示鉴权失败但去供应商后台看密钥是好的。原因是这个密钥参与凭据的对称加密换了之后密文解不出来。这个问题没有后悔药只能把每个供应商的 Key 重新填一遍。所以我现在的习惯是SECRET_KEY生成之后就写进密码管理工具部署脚本里直接从环境读取绝不在.env里手敲第二次。坑三沿用旧数据卷数据库容器起不来。现象是 db 容器启动几秒后退出日志里提到数据目录版本不兼容。原因通常是换了镜像的大版本而volumes/db/data还是旧版本写下的格式。解决方式是先备份卷再决定是回退镜像版本还是导出数据后重建卷再导入。千万不要在没备份的情况下删卷重来那等于把应用配置和会话全部清空。这类问题的根子在于升级前没读变更说明踩过一次就该记住大版本升级先读说明再动数据。5.2 运行阶段反向代理、出站网络、插件守护进程坑四挂在域名后面文件上传成功但预览 404。现象很割裂——上传接口返回成功点开文件却是空白或者 404。原因是几个“对外地址”变量还留空或者填的是内网地址后端生成的文件链接浏览器根本访问不到。解决方式是把控制台、应用、文件这几类对外地址统一填成外部可访问的完整地址重启 api 和 worker。填完之后注意历史文件的链接是按当时的配置生成的老数据可能需要重新上传。我一般会在部署清单里把这几项单独列一行配完逐项打勾。坑五知识库文档一直“排队中”或者插件安装转圈到失败。现象是上传了文档状态卡在处理中不动插件市场点安装也一直失败。前者去看 worker 日志常见原因是 worker 没起来、或者连不上队列后者多半是出站网络不通插件包拉不下来。还有一种隐蔽情况那个内网 API 地址填错插件守护进程连不上后端安装流程走一半就断。解决顺序是固定的——先docker compose ps确认 worker 和插件守护进程都在跑再看各自日志的最后几十行最后才怀疑网络策略。反过来先怀疑网络往往白折腾半天。顺带提一句排队中的另一个来源worker 并发数设得太小文档一多就排长队。这不是故障是容量问题调并发或者加机器别在日志里找不存在的错误。6. 升级与备份把「后悔药」提前做好升级这件事我的做法是先做一次完整的备份演练再谈升级。具体流程是这样停掉写入docker compose stop api worker导出一份数据库逻辑备份把关键卷打成一个包然后才去下载新版本的包、比对配置、拉镜像、启动。# 1. 停写入避免备份到一半数据还在变 docker compose stop api worker # 2. 逻辑备份数据库文件名带日期便于回滚定位 docker compose exec -T db pg_dump -U postgres \ $DB_DATABASE | gzip /backup/dify-db-$(date %F).sql.gz # 3. 打包文件存储和插件目录这两个丢了最肉疼 tar -czf /backup/dify-files-$(date %F).tar.gz \ volumes/app/storage volumes/plugin_daemon # 4. 恢复写入 docker compose start api worker参数上只有两点要注意-T是关掉伪终端分配不加的话在脚本里重定向会报错库名用变量引用别写死成dify不同版本默认库名可能不同写死容易导错库。升级时按这张表走每一步都有明确验证点出问题能立刻定位到是哪一步步骤动作验证点1备份数据库与关键卷备份文件大小非零能gunzip -t通过2用新包替换docker/目录保留原.env别整目录覆盖3diff 新旧.env.example新增键全部补齐废弃键确认可删4拉新镜像并启动docker compose ps全部 Up5观察 api 日志中的迁移输出无异常堆栈迁移正常结束6冒烟验证登录、跑一个已有应用、上传一份文档第三步是最容易被跳过、也最容易出事的一步。我吃过一次亏图快直接把新包里的docker/整个覆盖上去连带把.env也换成了样板密码和密钥全变数据库连不上插件守护进程也起不来。那次之后我改了个习惯——升级前先把docker/目录整个复制一份到/tmp/dify-docker-$(date %F)再往里覆盖出问题三分钟就能切回去。这算不上什么高级技巧但它救我至少两次。还有个小细节值得单独记升级完成后别急着宣布成功先跑一遍“长链路”——上传一份几十页的文档等它完成解析和索引再对它提问一次。这条链路覆盖了 api、redis、worker、向量库、模型供应商五个环节任何一环有版本兼容问题都会在这里暴露出来。只测登录页和首页等于什么都没测。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询