只要玩过 Dify 的人,十有八九都经历过这么一幕:满怀期待下载了最新版,打开 Docker Desktop,敲下docker compose up -d,屏幕上哗啦啦拉起十几个容器,你以为大功告成,结果五分钟之后再去看,api、worker 那个容器已经退出了,日志一翻全是 Connection refused。接着去查端口、改配置、清缓存,折腾到半夜,最后发现是内存不够把容器 OOM 掉了。
这篇东西就是写给准备部署 Dify 1.17 的新手,同时也适合部署完跑了几天又莫名出问题的朋友。我会把「精简部署」和「问题排查」这两件事揉在一起讲:先讲清楚这个平台的容器架构和哪些组件可以砍、哪些不能动,然后从 .env 配置、启动命令、模型接入讲到知识库同步、向量库连不上、端口冲突、OOM 这类高频故障的完整排查链路。你不需要是 Docker 老手,只要照着操作,大概率一次跑通。
1. 部署 Dify 1.17 前,先把这些容器角色的关系捋清楚
1.1 Dify 不只是一个“聊天网页”
很多新手第一次部署 Dify,以为它就是装一个聊天机器人前台,实际上 Dify 是一个完整的 LLM 应用开发平台。你在浏览器里看到的界面,只是整套系统中的「前端展示层」;真正干活的是后端 API、异步任务 Worker、提供元数据存储的 PostgreSQL、负责消息队列的 Redis,以及做知识库向量检索的向量数据库。
这个概念不搞清楚,后面遇到问题就很难定位。比如你在后台创建了一个知识库,上传文档之后状态一直显示“同步数据中”,这不是前端卡住了,而是 Worker 容器在后台处理文档分块和向量化。如果 Worker 挂了,或者 embedding 模型没配好,前端永远只会转圈。所以当你把docker compose up -d敲下去的时候,脑子里一定要有「我拉起来了一整套微服务」的概念,而不是一个软件。
理解到这个层面之后,再看日志、查容器状态,你才知道该去看哪个容器的日志。部署排错最忌讳的就是盯着网页的报错信息猜,因为你看见的只是结果,真正的原因都躲在容器日志里。
1.2 1.17 版本默认会拉起哪些容器
Dify 1.17 的docker目录下自带一份docker-compose.yaml,默认配置会启动的服务大致如下。我按职责分好了组,方便你对照:
| 容器服务 | 职责说明 | 是否能精简 |
|---|---|---|
| nginx | 整个平台的入口网关,转发前端请求和后端 API | 必须保留 |
| web | 前端静态页面,也就是浏览器里看到的控制台 | 必须保留 |
| api | 后端核心服务,提供 REST API、工作流执行入口 | 必须保留 |
| worker | 异步任务执行器,负责知识库文档处理、数据集索引、事件调度 | 必须保留 |
| db | PostgreSQL 数据库,保存用户、应用、工作流等元数据 | 必须保留 |
| redis | 缓存和消息队列,协调 api 与 worker 之间的任务通信 | 必须保留 |
| weaviate | 默认向量数据库,知识库的向量索引和检索靠它 | 按需替换 |
| ssrf_proxy | SSRF 防护组件,所有出站 HTTP 请求都经过它过滤 | 默认保留 |
| sandbox | 代码执行沙箱,用于工作流中“代码执行”节点 | 可关闭 |
| plugin_daemon | 插件守护进程,管理插件市场的安装和运行 | 默认保留 |
| etcd | 给 plugin_daemon 存分布式元数据用的键值库 | 默认保留 |
| doris | 可选的数据分析组件,用于运营数据看板 | 可关闭 |
这里有一个非常容易踩的坑:很多人不知道doris在较新版本里被加入了默认编排文件。Doris 是 Apache Doris,一个 OLAP 分析数据库,普通新手根本用不上,但它默认会占掉不少内存。如果你的机器资源紧张,第一件事就是把 Doris 相关服务注释掉,而不是去网上搜“为什么我的 Dify 这么卡”。
1.3 哪些服务可以“精简”掉,哪些千万别动
我的建议非常明确:在你不清楚某个容器是干什么的之前,一律保留默认配置。等你把 Dify 跑通、玩明白了,再考虑精简。
如果确实需要精简,优先级如下:
- 不需要工作流里的“代码执行”节点,可以关闭
sandbox。这个组件对新手绝大多数场景没有用,关掉能省下不少资源。 - 用不上运营分析看板,可以注释掉
doris。Dify 的完整功能核心是工作流、知识库、Agent,运营分析是后期才需要的扩展能力。 - 如果内存实在紧张,可以把向量数据库从
weaviate换成pgvector方案。Pinecone、Weaviate 这类向量库本质上就是帮你做向量检索,而 pgvector 是 PostgreSQL 的插件扩展,可以直接复用你已经有的 db 容器,省掉一个独立的数据库服务。具体做法是在.env里设置VECTOR_STORE=pgvector,并确保 db 容器用的镜像是带 pgvector 扩展的版本。
有一点要反复强调:api、worker、db、redis这四个绝对不能砍。尤其是 worker,很多新手以为我不用批量任务就可以关掉它,结果知识库上传之后永远卡在“同步中”,后台还在莫名其妙地报错。worker 承担的不只是批处理,知识库的文档切分和向量化、定时触发的工作流、应用的事件处理,全部依赖它。
2. 精简部署的环境准备与 .env 关键项设置
2.1 硬件基线:文档里写的 8G 内存不是闹着玩的
官方文档建议的最低配置是4核CPU、8G内存、50G磁盘,这个数字对新手来说是真实底线,不是虚标。实际部署时你会发现,光是 api、worker、plugin_daemon、weaviate 这几个 Java/Python 进程一起吃内存,4G 内存的机器分分钟见底。
我自己第一次在 4G 内存的旧笔记本上跑 Dify,docker compose up -d倒是成功了,但打开页面要等两分钟,创建知识库上传文档后,worker 直接被系统 OOM Kill。后来加了 2G swap,再把 sandbox 和 doris 关掉,才勉强跑起来。
所以如果你手头的机器内存低于 8G,建议先做两件事:一是参考上面第1节把能关的组件关掉,二是给 Docker 设置好内存限制。Windows 和 macOS 的 Docker Desktop 可以在设置里调整资源上限,Linux 上可以通过 docker 的 systemd 配置或者/etc/docker/daemon.json来控制。
再一个容易被忽略的点:磁盘空间。Dify 的镜像加起来有好几 GB,PostgreSQL、Weaviate 跑起来之后数据还会持续增长。装上之后如果你的磁盘剩余空间不足 10G,容器随时可能因为写不进去而死掉。部署之前用df -h看一下磁盘,确保至少留出 15G 可用空间。
2.2 获取 Dify 1.17 发布包:用 zip 而不是 git clone
获取 Dify 代码有三种常见方式:GitHub Release 页面下载 zip 包、git clone仓库、直接用 Docker 镜像。新手我建议下载 Release 页面的 zip 包。
原因很简单:git clone 拿到的是 trunk 代码,可能是比当前稳定版新但也可能有问题;而 Release 里的 zip 包版本明确,对应关系清楚,出了问题也好搜解决方案。Dify 的 GitHub 仓库叫langgenius/dify,在 Release 页面找到 1.17 版本,下载Source code (zip)即可。
下载之后解压,你会发现里面有个docker文件夹,这个文件夹才是部署的核心。不要解压完就傻眼,那个dify-main文件夹是整个项目源码,部署只需要进docker子目录。所有的编排文件、环境变量模板都在里面。
2.3 从 .env.example 到 .env:这步决定后面一半的坑
在docker目录下,你会看到一个.env.example文件。这个文件是环境变量模板,Dify 所有可配置项都通过它控制。真正生效的配置是.env文件,Docker Compose 启动时会自动读取。
新手最常见的错误有两个:一是直接把.env.example改名成.env,二是完全忘记复制这个文件,直接docker compose up -d。前者问题不大但后续升级会麻烦,后者会让 Compose 里一堆变量为空,服务起不来或者起来就崩。
正确的操作是复制一份:
# Linux / macOS cp .env.example .env # Windows CMD copy .env.example .env # Windows PowerShell Copy-Item .env.example .env注意,Windows 下如果你在文件夹空白处右键选择“在终端中打开”,默认是 PowerShell;如果你在地址栏输入 cmd 回车,打开的是命令提示符。很多新手用cp命令在 CMD 里报错,就是这个原因。
2.4 .env 里哪些配置项必须改,哪些可以放着不管
.env文件很长,新手不需要每一行都看懂,但下面这几个一定要知道是干什么的:
| 配置项 | 作用 | 建议 |
|---|---|---|
| SECRET_KEY | 应用签名密钥,用于会话加密等 | 必须换成随机长字符串,别用默认值 |
| POSTGRES_PASSWORD | 数据库密码 | 必须换掉默认值 |
| VECTOR_STORE | 向量数据库类型 | 默认 weaviate,想精简可改为 pgvector |
| DIFY_PORT | Web 服务对外端口 | 默认 80,80 被占用时可以改成 8080 |
| EXPOSE_PLUGIN_MARKET | 是否启用插件市场 | 企业内网建议设为 false |
关于 SECRET_KEY,我见过有人在多台机器之间直接拷贝.env,SECRET_KEY 也是一样的,这样做其实问题不大,但如果你曾经把 SECRET_KEY 暴露到公网(比如不小心提交到了公开仓库),那就一定要换。否则别人可以伪造签名数据。
另外提醒一句:每次 Dify 大版本升级,.env.example都会加入新的配置项,升级时记得比对一下新旧 example 文件的差异,把新增的项补到自己的.env里。很多升级后出现诡异问题的案例,都是因为旧.env缺了新版本要求的配置。
3. 手把手启动 Dify 1.17:解压、改配置、跑起来
3.1 Windows 下打开终端并进入 docker 目录
这个点看起来基础,但确实卡住过不少人。假设你把 zip 解压到了D:\dify-main,那么 docker 编排目录是D:\dify-main\docker。
正确操作:在文件资源管理器里进入到dify-main\docker文件夹,点击地址栏,输入cmd,回车。这样打开的 CMD 窗口工作目录就直接定位到了 docker 文件夹,省去手动 cd 的麻烦。
然后在 CMD 里依次执行:
copy .env.example .env此时会提示“已复制 1 个文件”,然后你就可以编辑.env了。Windows 下可以用记事本打开.env文件,或用 VS Code 编辑。
3.2 执行启动:docker compose 而不是 docker-compose
确保 Docker Desktop 已经启动,托盘里的鲸鱼图标是正常运行状态,然后执行:
docker compose up -d这里注意:新版本 Docker 官方推荐用docker compose,中间有一个空格,这是 Docker Compose V2 的插件模式。老教程里写的docker-compose(带横杠)是老版本的独立命令。如果你的环境是新装的 Docker Desktop,用docker compose肯定没问题;如果在旧 Linux 服务器上,可能只有docker-compose。
第一次启动时,Docker 会从镜像仓库拉取所有需要的镜像,根据你的网络环境,这步可能需要一段时间。国内网络环境下,如果拉取慢或者超时,可以考虑给 Docker 配置镜像源,但这里我不展开讲网络相关的话题,只需要知道这是正常的网络耗时过程即可。
启动完成后,执行docker compose ps查看容器状态。你需要看到所有服务处于Up状态,或者Up (healthy)状态。如果看到Restarting、Exited这类状态,说明某个服务启动失败,先别急着打开页面,先去查日志。
3.3 为什么网页打不开:序列依赖和迁移时间
Dify 各容器之间有启动顺序依赖。第一次启动时,db 容器要先初始化数据库,api 容器会执行数据库迁移脚本,这个迁移过程可能要持续几分钟,期间你访问页面会看到 502 或连接失败。
很多新手这时的第一反应是“坏了”,其实不是。正确等待姿势是:
docker compose logs -f api看到日志中出现类似Database migration completed或对应的迁移完成输出之后,再尝试打开浏览器。
然后访问http://localhost(如果你没改 DIFY_PORT,默认就是 80 端口)。首次打开会出现初始化页面,让你设置管理员邮箱和密码。这里建议用真实常用邮箱,忘了密码可以找回;密码尽量设置得复杂一点,因为你有管理员权限之后,可以配置模型供应商、查看所有应用数据。
3.4 给关键容器加资源限制:一份可以“抄作业”的 compose 片段
如果你确实想精简资源占用,但又不想大动干戈改架构,最稳妥的做法不是删服务,而是给每个容器加内存上限。在docker-compose.yaml里,给对应服务增加mem_limit配置:
api: image: langgenius/dify-api:1.17.0 mem_limit: 2g restart: always environment: MODE: api worker: image: langgenius/dify-api:1.17.0 mem_limit: 2g restart: always environment: MODE: worker weaviate: image: semitechnologies/weaviate:1.19.0 mem_limit: 1g注意,这里我对 Dify 1.17 的镜像 tag 只做示意,实际版本号要以你下载的 Release 里的docker-compose.yaml为准。加 mem_limit 的原理是:当某个容器内存使用超过限制时,会被 Docker 强制限制而不是继续拖垮整个宿主机的内存。比如 weaviate 如果查询量大了会吃掉大量内存,限制在 1G 以内,最多就是查询变慢,不会把宿主机搞死。
加了资源限制之后,记得重新创建容器:
docker compose up -d --force-recreate3.5 更新代码和重启服务:改完配置别忘这步
新手经常犯的一个错:改了.env文件之后,只是简单地docker compose restart。但restart只是重启容器,不会重新读取.env里的新环境变量。要重新读取环境变量,必须重新创建容器:
docker compose up -d这个命令会检测到配置变化,自动重新创建受影响的容器。如果只是改了代码文件或者想强制重建,可以用:
docker compose up -d --force-recreate记住一个原则:改.env用up -d,改代码想重置运行环境用up -d --force-recreate,只是临时故障清理则用restart。
4. 模型接入:DeepSeek 云 API 与 Ollama 本地模型的两种姿势
4.1 接入 DeepSeek 等云 API:五分钟搞定
Dify 本身不带大模型能力,它只是一个编排平台。所以部署完成后的第一步,是接入一个模型供应商。
在管理后台左侧菜单找到「设置」,切到「模型供应商」,搜索 DeepSeek,点击添加。需要填两个东西:API Key 和 API 服务地址。DeepSeek 的 API 地址官方会给一个 base_url,你只需要把申请到的 Key 填进去,保存即可。
这里有个细节:Dify 对模型供应商做了“模型类型”的区分。你添加了 DeepSeek 之后,最好分别把「LLM」和「Embedding」两类模型都配置一下。LLM 是聊天对话用的,Embedding 是知识库做向量化用的。如果你只配了 LLM 没配 Embedding,知识库照样用不了,因为文档没法转换成向量。
4.2 接入 Ollama 本地模型:host.docker.internal 这个坑必须知道
本地部署党最爱的方案是用 Ollama 跑一个本地模型,比如 qwen2.5、deepseek-r1 之类,然后把 Dify 接上去,实现完全离线的大模型应用。
思路很简单:宿主机安装 Ollama,拉取模型,然后在 Dify 的模型供应商里选 Ollama,填上 Ollama 的 API 地址。
但这里有一个新手几乎必踩的坑:Dify 跑在 Docker 容器里,容器里的localhost是容器自己,不是你的宿主机。如果你在 Dify 里填http://localhost:11434,Ollama 永远连不上,因为容器内部没有这个端口。
正确填法取决于你的操作系统:
- Windows / macOS(Docker Desktop):填
http://host.docker.internal:11434。Docker Desktop 会默认把host.docker.internal解析到宿主机。 - Linux:这个域名不一定可用,建议直接填宿主机的局域网 IP,比如
http://192.168.1.100:11434。
还有一个隐藏坑:Ollama 默认只监听127.0.0.1,也就是只允许本机访问。由于 Docker 容器访问宿主机走的是网络栈,即使你填对了地址,也会被 Ollama 拒绝。需要让 Ollama 监听所有网卡:
OLLAMA_HOST=0.0.0.0 ollama serve如果你用的是 Windows 的 Ollama 桌面版,可以在设置里找到环境变量,设置OLLAMA_HOST=0.0.0.0后重启应用。
4.3 embedding 模型不配好,知识库永远卡在“同步数据中”
我前面反复提到知识库同步问题,这里展开讲。创建知识库之后,你上传文档,Dify 会经历:文档解析、文本分块、Embedding 向量化、写入向量数据库 四个阶段。其中 Embedding 向量化必须由 embedding 模型完成。
如果你没有配置任何 embedding 模型,或者配置文件里的 embedding 模型不可用,那么知识库状态会一直停在“同步数据中”,或者同步完成后但检索不出任何内容。
本地方案一般用bge-m3、bge-large-zh-v1.5这类中文效果好的模型,通过 Ollama 跑起来之后,在 Dify 里添加 Ollama 类型的 Embedding 模型即可。如果你不想折腾本地向量化,直接配一个云端的 embedding 模型也行,Dify 的平台里可选的大模型服务商基本都提供 embedding 能力。
调试的方法很简单:在 Dify 后台的「模型供应商」页面,每个模型旁边都有个「测试」按钮。测试不通,说明模型配置有问题,别去纠结知识库本身。我见过太多人知识库上传失败,跑去改解析配置、改分块策略,其实只是 embedding 模型没配好。
4.4 SSRF 白名单:为什么远程模型正常,本机模型就是调不通
Dify 出于安全考虑,默认会启用 SSRF 防护组件,所有从 Dify 发出的 HTTP 请求,都要经过这个组件的过滤。它的作用是防止恶意用户诱导服务器访问内网地址。这个设计本身没问题,但它也会误伤你。
如果你在自定义工具、HTTP 请求节点、插件里访问了本机的服务(比如http://host.docker.internal:11434或者http://192.168.1.5:8080),很大概率会被 SSRF 防护组件拦截,报错信息类似于“SSRF request failed”或“Forbidden”。
解决办法不是关掉 SSRF 组件,而是去管理后台「设置」-「安全」-「SSRF 访问规则」里,把需要访问的域名或 IP 加入白名单。比如把host.docker.internal、192.168.1.5这些地址加进去,保存后再试。
这个坑特别隐蔽,因为你在浏览器里测试接口是通的,到了 Dify 工作流里就报错。记住一个排查顺序:先看请求有没有到 SSRF 白名单,再看目标服务是否真的开放了端口,最后才去怀疑代码逻辑。
5. 启动后的验证、数据备份与版本升级
5.1 怎么判断 Dify 真的健康:别只看页面能打开
页面能打开不代表系统健康。我建议部署完做一套体检动作:
docker compose ps看所有容器是否Up。然后打开后台,创建一个小应用,跑一个最简单的对话流程,再创建一个小知识库传一个文件进去。这一步能验证三个关键链路:模型调用是否通、worker 是否在工作、向量库是否正常读写。
还有一个细节:查看容器状态时留意Up (healthy)和Up的区别。healthy表示容器通过了健康检查,Up只是进程还活着但没做健康检查。如果某个容器一直处于running但状态不是 healthy,比如 db 或 redis,也要警惕。
5.2 日志是排错的第一现场
Dify 的问题几乎都能从日志中找到答案。几个最常用的查看命令:
# 查看 api 容器日志,跟踪输出 docker compose logs -f api # 查看 worker 容器最近 100 行日志 docker compose logs --tail=100 worker # 查看所有容器日志(比较吵,适合确认整体情况) docker compose logs日志里出现ERROR、Traceback、Connection refused、OOMKilled这些关键词,基本就是根因所在。如果你把日志截图发到社区求助,别人也才能帮你定位。
5.3 数据备份:比你想的简单,但不要跳过
Dify 的数据分为几部分:PostgreSQL 里的元数据(用户、应用、工作流配置)、向量数据库里的知识库向量、本地存储的上传文件。最省事的备份方法是直接备份 Docker 的数据卷。
先查看有哪些数据卷:
docker volume ls你会看到docker_db_data、docker_weaviate_data、docker_storage之类的卷。备份其实就是把这些卷的内容拷贝出来。比如备份 PostgreSQL:
docker run --rm -v docker_db_data:/data -v D:/backup:/backup alpine tar czf /backup/db_data.tar.gz /data恢复时反过来操作即可。如果你不想折腾命令,还有一个更笨但实用的办法:直接把整个 docker 文件夹和所有相关数据卷目录拷贝一份到移动硬盘。只要数据卷在,Dify 重新装起来数据都还在。
记住,升级之前一定要备份。Dify 升级过程中如果数据库迁移失败,没有备份就只能重来,那种看着几百条工作流配置消失的滋味不好受。
5.4 从 1.17 升级到后续版本:完整动作序列
Dify 的版本更新很频繁,很多功能修复和模型支持都需要升级才能用上。升级步骤其实不复杂:
- 备份
.env文件和所有数据卷。 - 下载新版本代码,解压覆盖旧的 docker 文件夹(保留你自己的
.env,不要用新的.env.example直接覆盖)。 - 对比新旧
.env.example,把新出现的配置项手动补充到自己的.env中。 - 进入 docker 目录,执行
docker compose down停止所有容器。 - 执行
docker compose pull拉取新版本镜像。 - 执行
docker compose up -d重新启动。
升级完成后,数据库迁移会自动执行,首次启动同样需要等待几分钟。期间不要强制重启容器,迁移中断是升级失败最常见的原因。
这里特别提一下 Windows 下的升级:很多人习惯直接把整个文件夹删掉再解压新的,这样会把.env也删掉。正确做法是解压新包之后,手动把旧的.env复制进新目录再执行升级。
6. Dify 1.17 实战问题排查链路:从现象到根因
6.1 端口被占用:nginx 容器起不来
现象是docker compose ps里 nginx 一直Restarting,日志里报bind: address already in use。
排查链路:
# 查看 80 端口被哪个进程占用 netstat -ano | findstr :80输出里最后一列是 PID,然后用:
tasklist | findstr <PID>就能看到是哪个程序占了 80 端口。常见的凶手是 IIS、Apache、另外一个 Nginx,或者某些开发工具自带的 Web 服务。
解决办法有两个:一是停掉那个进程,二是给 Dify 换个端口。我更推荐第二种,省事且不干扰现有服务。编辑.env,设置DIFY_PORT=8080,然后docker compose up -d重建容器。之后访问http://localhost:8080。
同理,443 端口被占会导致 HTTPS 入口起不来,但新手短期用 HTTP 就够,不用急着配置证书。
6.2 容器反复重启:内存不足导致的 OOM Kill
现象是 api、worker、plugin_daemon 这些容器过一段时间就重启一次,日志里有Killed字样,宿主机执行dmesg能看到Out of memory。
排查链路:
# 查看容器内存占用排名 docker stats --no-stream看到哪个容器内存涨到接近限制值,基本就实锤了。Dify 的 Python 后端和 Weaviate 都是内存大户,8G 的机器默认配置下很容易触发 OOM。
解决思路按优先级排列:
- 注释掉
doris和sandbox,把weaviate的mem_limit降到 1g。 - 给宿主机加 swap 空间。Linux 上加 swap 很简单,Windows 上调整虚拟内存。
- 如果还不行,把向量数据库从 weaviate 换成 pgvector,省掉一个独立服务的内存开销。
我实测下来,一个关闭 sandbox 和 doris、weaviate 限制在 1g 的 Dify,4G 内存机器可以稳定跑,但别同时开太多工作流并发。
6.3 知识库同步一直转圈:向量数据库连接失败
现象是后台创建知识库、上传文档之后,状态永远停留在“同步数据中”,或者同步完成后检索不到内容。
排查链路分三步:
一看 worker 容器状态:
docker compose ps worker如果 worker 没起来,知识库永远处理不了文档。没起来的原因大概率是 OOM,回到 6.2 的问题处理。
二看向量数据库状态:
docker compose logs weaviate | tail -50如果 weaviate 报连接错误或者反复重启,说明向量库本身有问题。可以先尝试:
docker compose restart weaviate再不行就考虑是不是磁盘写满了,docker system df查看 Docker 占用的磁盘空间。
三看 embedding 模型配置。到「模型供应商」页面点 embedding 模型的测试按钮,如果测试失败,说明模型调用链路不通。这一环节最容易忽视,因为很多人只关心 LLM,不关心 embedding,结果知识库功能就是死活不工作。
6.4 模型调用报错:SSRF 白名单和 DNS 解析问题
现象是在工作流里调用自定义工具,或者调用本地 Ollama 服务时,报出类似SSRF request failed、Connection error的错误。
排查链路:
先确认目标地址是否在白名单里。管理后台「设置」-「安全」-「SSRF 访问规则」,把目标域名或 IP 加入白名单。加入后不用重启容器,立即生效。
如果加了白名单还不行,再看 api 容器日志:
docker compose logs api | grep -i "ssrf\|error"日志里如果有 DNS 解析失败的信息,说明容器内 DNS 配置有问题。可以在.env里检查有没有关于 DNS 的配置项,或者检查宿主机 DNS 是否正常。企业内网环境尤其容易出现自建 DNS 解析外部域名失败的情况。
6.5 插件市场加载失败 / plugin_daemon 异常
现象是后台打开插件市场一直转圈,或者 plugin_daemon 容器退出重启。
排查链路:
docker compose ps etcd plugin_daemonplugin_daemon 依赖 etcd 做元数据存储,如果 etcd 起不来,插件功能全部不可用。etcd 默认监听 2379 端口,这个端口也容易被本机其他服务占用,可以用 6.1 的方法排查端口。
另外,企业内网环境访问不了插件市场地址时,插件市场会一直加载失败。这时可以把.env里的EXPOSE_PLUGIN_MARKET改为false,禁用插件市场,不影响 Dify 核心功能。
6.6 登录后报系统错误:数据库迁移未完成
现象是初始化安装完成、能正常打开登录页面,但登录之后所有页面都在报“系统错误”,后台日志刷出一堆数据库字段不存在的错误。
这种问题基本可以断定是 api 容器启动时数据库迁移没有跑完,或者迁移过程被中断。常见于内存不够导致迁移进程被 OOM,或者升级时数据库版本不兼容。
处理办法:
docker compose down docker compose up -d db先把 db 容器单独拉起来,等它完全就绪后再启动其他服务:
docker compose up -d如果还不行,就查 api 日志里的迁移报错信息,重点看是哪张表、哪个字段出错。按日志提示修复,比什么都可靠。
最后分享两个我自己的实操习惯。第一,日志优先。Dify 的任何异常,我都先docker compose ps看谁挂了,再docker compose logs --tail=200 <容器名>看它为什么挂,基本能解决九成问题。别上来就删容器重建,那只是碰运气。第二,备份成习惯。升级前备份.env和数据卷,出问题 5 分钟还原;不备份的升级,就是开盲盒。做多了你会发现,部署 Dify 本身不难,难的永远是那些“差一点没想到”的细节。