最近帮同事从零搭了一套 Dify,说实话真正把我卡住的不是 Dify 本身的配置,而是最基础的 Docker 镜像拉取。Dify 在我实际用来做 LLM 应用开发平台已经有一段时间了,它解决的核心问题就是让你不用从零写前后端和编排逻辑,通过可视化的方式把大模型、工作流、知识库、Agent 这些能力串起来。这篇把我在 Docker 下部署 Dify 的完整过程记录下来,包括镜像源配置、Compose 启动、Ollama 本地模型接入、Windows 下的坑以及后续升级维护,给准备做 Dify 本地部署的朋友一份可以直接照着操作的参考。
1. 先理清楚:Docker、Dify、镜像站这三件事是什么关系
1.1 Dify 不是大模型,而是大模型应用的操作台
很多人第一次看到 Dify 会误以为它是一个“可以本地跑起来的 ChatGPT”,实际上它的定位完全不同。Dify 是一个开源的 LLM 应用开发平台,你可以把它理解成大模型时代的“可视化后端”。它不会自己产生模型能力,而是帮你连接各种模型来源,包括 OpenAI 兼容接口、Azure OpenAI、 Anthropic、Ollama 本地模型等,然后在这个基础上快速搭建应用。
我举一个最常见的例子:企业想做一个基于内部文档的问答机器人。传统做法是你需要先搞定文字嵌入、向量数据库、Prompt 模板、对话管理、后台管理界面,整体开发周期少说一两个星期。但在 Dify 里,你只需要在界面上导入文档、选择分段策略、配置一个 Embedding 模型,再选一个聊天模型,一个带知识库能力的问答应用就算搭好了。整个过程中你不需要写 Python 或 JavaScript 代码,它把 RAG、Agent、工作流这些底层逻辑都封装成了可视化节点。
这个概念对后面理解部署架构非常关键。因为 Dify 不是一个单一体应用,它为了保证这种开箱即用的体验,在底层同时跑着 API 服务、Worker 异步任务、前端页面、PostgreSQL 数据库、Redis 缓存、向量数据库、沙箱环境等一整套服务。如果没有 Docker 这种容器化工具,光把这些依赖装齐就是灾难,这也是为什么官方主推 Docker Compose 部署的原因。
1.2 为什么用 Docker Compose 而不是手动装环境
我在第一台测试机上曾经尝试过不依赖 Docker 的部署方式,结果在依赖环节就折腾了很久。Python 版本冲突、Node 版本不符合要求、PostgreSQL 扩展缺失,每一个问题都在消磨耐心。后来我老老实实切回 Docker 方案,整个部署过程就变得顺理成章了。
Dify 官方仓库的 docker 目录下有一个 docker-compose.yaml 文件,里面一次性声明了所有需要的服务。包括 nginx 做反向代理,api 容器运行后端接口,worker 容器处理异步任务,web 容器跑前端,还有 postgres、redis、weaviate 或 qdrant 这类基础设施。使用 Docker Compose 带来的第一个好处是环境隔离,我不会因为本机已经装了 MySQL 8.0 或者 Redis 而担心端口冲突或版本干扰;第二个好处是升级和回滚非常干净,所有服务都跟着镜像版本走,不会出现升级了代码但是依赖库没升级的尴尬情况。
当然 Docker 方案对应的学习成本也很明显,如果你从来没接触过 docker compose 命令,刚看到那一大串 YAML 文件时会有点发怵。但实际需要你手动改动的点很少,大部分情况下只要把 .env 配置文件里几项关键参数调好,剩下就是等待容器启动。后面我会把每一步细节都写出来。
1.3 “镜像站”到底卡在哪里:Docker Hub 与拉取慢的问题
Dify 相关镜像默认都发布在 Docker Hub 上,比如 langgenius/dify-api、langgenius/dify-web 这些。在国内网络环境下,直接 docker pull Docker Hub 上的镜像经常会出现几十 KB 每秒甚至超时中断的情况,这是很多新手第一道坎。
镜像加速的原理其实不复杂。Docker 客户端默认从 Docker Hub 拉取镜像,但如果配置了 registry-mirrors,Docker 会优先从你指定的镜像仓库拉取。这类镜像仓库可以理解成 Docker Hub 的只读缓存节点,它会提前同步热门镜像,你在国内访问时速度会快很多。需要注意,每个镜像加速地址的同步策略不一样,而且部分公共地址有一定时效性,过期后拉取又会变慢,所以我实际更推荐通过云厂商控制台获取专属加速地址,稳定性会好不少。
但就算配好了镜像加速,启动 Dify 时仍可能遇到部分镜像拉不下来的情况。我的经验是不要在一个加速地址上死磕,可以把阿里云、DaoCloud 等几个公开地址轮着试,哪个能拉下来用哪个。还需要提醒一点,镜像加速只作用于 Docker 客户端,如果你后续在 Dify 容器里安装 Python 依赖慢、下载 Nacos 或其他组件慢,那是另一回事,需要给容器配置对应的软件源,不能混为一谈。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 部署前的硬环境准备:版本、内存、端口
2.1 Docker 与 Compose 版本要先检查
我见过很多部署 Dify 失败的案例,最后排查下来根本不是 Dify 的问题,而是宿主机 Docker 版本太老导致镜像内某些指令无法执行。Dify 对 Docker 版本要求不算苛刻,但为了少踩坑,建议使用 Docker 20.10 以上,并确保 Docker Compose 是 v2 版本。
检查方法很简单:
bash复制docker -v
docker compose version
如果你执行 docker compose version 报错,说明系统里只有旧版 docker-compose,命令需要写成 docker-compose。Dify 官方文档的示例基本都按新版 Compose 来写,所以我建议直接把 Docker 升级到较新版本,避免命令转换带来的麻烦。
Linux 环境下如果用的是官方安装脚本装的 Docker,卸载旧版本后重新安装即可:
bash复制sudo apt-get remove docker docker-engine docker.io containerd runc
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Windows 环境我强烈建议用 Docker Desktop,它会自动管理 Docker Engine 和 Compose 插件,安装后直接在 PowerShell 里执行 docker compose 就能用。唯一要注意的是 Docker Desktop 依赖 Windows 的虚拟化功能,如果 BIOS 里没开虚拟化,启动时会直接报错失败,这个在第 4 章我会专门讲。
2.2 内存、CPU 与端口规划不能凭感觉
Dify 官方给的最低配置是 2 核 4G 内存,但这是个“能跑起来”的底限,而不是“舒服运行”的标准。我自己实测下来,如果只是简单对话应用,4G 内存勉强够;一旦开启知识库、上传文档并做向量化,内存占用会明显飙升,因为 Dify 还要跑 PostgreSQL、Redis、向量数据库,再加上 API 和 Worker 两个 Node 进程,整体内存压力不小。
我建议个人学习环境至少给 8G 内存,团队使用场景则最好 16G 以上。如果本机内存比较紧张,可以考虑关掉一些不常用的后台程序再启动 Dify,或者用 docker stats 命令实时观察各容器占用的资源,找出最吃内存的服务做针对性优化。
端口方面,Dify 默认通过 Nginx 对外暴露 80 和 443 端口。如果你本机 80 端口已经被占用,比如 Windows 上 IIS 或某些开发工具占用了 80,直接启动会报端口冲突。推荐在安装前先规划好端口,可以改成一个不常见的端口,比如 18000,避免和本机已有服务打架。
2.3 镜像加速源配置:Linux 与 Docker Desktop 两种写法
镜像加速源的配置本质上就是给 Docker 加一个 registry-mirrors 参数。Linux 环境下,Docker 的配置文件路径是 /etc/docker/daemon.json,如果文件不存在则手动创建:
json复制{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://你的专属加速地址.mirror.aliyuncs.com"
]
}
改完一定要重启 Docker 再拉起容器,否则不会生效:
bash复制sudo systemctl daemon-reload
sudo systemctl restart docker
Docker Desktop 的配置图形化一些:打开 Docker Desktop,点击右上角设置图标,进入 Docker Engine 选项卡,你会在 JSON 编辑器中看到当前配置,把 registry-mirrors 加到里面,然后点击 Apply & Restart 即可。
配置好后可以用 docker info 查看 Registry Mirrors 是否已经生效,然后随便拉一个小镜像做速度测试。
这里我想多说一句:加速源只是解决一部分网络问题。如果拉取 Dify 大镜像时已经从 Docker Hub 切换到了加速地址,但速度依然不理想,可以考虑分多次拉取单个镜像而不是一次性 docker compose up,因为 Compose 启动时如果没有本地缓存,会并发拉取多个镜像,网络拥塞会放大失败率。一个一个地手动 docker pull,逐个确认下载成功后,再执行启动命令,成功率会高得多。
3. Dify 正式落地:从源码获取到跑通第一个应用
3.1 获取 Dify 源码与镜像清单
Dify 的部署文件是随源码一起发布的,所以第一步是获取源码。官方代码托管在 GitHub 上,我通常直接下载 Release 页面的 zip 压缩包,再传到服务器解压,比用 git clone 更省事。
解压之后进入 docker 目录,你会发现有这些核心文件:
- docker-compose.yaml:编排文件,定义所有容器
- .env.example:环境变量模板,部署前需要复制成 .env
- volumes 相关目录:用于持久化数据
用命令初始化环境变量:
bash复制cd dify/docker
cp .env.example .env
这一步非常重要。很多人直接执行 docker compose up -d 后发现很多配置不对,就是因为跳过了 .env 初始化。.env 文件是 Dify 所有运行参数的“总开关”,包括对外端口、数据库连接、向量库类型、模型密钥默认值等。官方模板里的默认值是可以直接跑通的,但是有几项你必须根据自己的本机情况调整。
3.2 按需修改 .env 里的关键项
先打开 .env 文件,找到以下几个关键配置:
EXPOSE_NGINX_PORT 是 Dify 对外的 HTTP 入口端口,默认 80。如果你的服务器或本机已经把 80 端口给了其他服务,一定要在这里改掉。假设我改成了 18000,那安装完成后访问地址就是 http://localhost:18000。
接下来还要看 CONSOLE_API_URL、APP_API_URL、APP_WEB_URL 这三项,它们控制的是前端页面和后端 API 的实际访问地址。如果部署在一台公网服务器上,需要把这些地址改成服务器 IP 或域名;如果只是本地虚拟机测试,保持默认的 http://localhost 即可。这里最容易出的问题是:只改了 EXPOSE_NGINX_PORT,却没同步改这三个 URL,结果登录后页面能打开,但调用接口时全部指向 80 端口,出现各种 403 和 404 错误。
VECTOR_STORE 决定知识库功能使用哪种向量数据库。Dify 默认支持 weaviate、qdrant、milvus 等,默认模板里通常用的是 weaviate。作为个人学习使用,weaviate 足够;如果后续数据量很大、并发很高,可以再切 qdrant。
数据库这块默认用的是 PostgreSQL,不是 MySQL。如果你看到网上有人说 Dify 需要 MySQL 8.0,那个其实是把 Dify 和普通 Web 项目搞混了。Dify 的元数据存储默认走的 PostgreSQL 和 Redis,向量数据则走向量数据库,这样的设计是为了支持它复杂的多租户、异步任务和检索逻辑。如果你确实需要把 PostgreSQL 替换成外部 MySQL 8.0,理论上可以通过修改 DB_ 前缀的配置实现,但我不建议这么干,一个是官方支持的力度有限,另一个是替换后迁移成本很高,除非你本来就对 Dify 内部表结构非常熟悉。
3.3 compose 启动命令与首启观察
.env 配置好之后,进入 docker 目录执行:
bash复制docker compose up -d
第一次启动会拉取大量镜像,时间长短取决于你的网络环境和镜像加速源配置。启动后不要急着关终端,先用下面命令查看容器状态:
bash复制docker compose ps
正常状态下各服务的 STATE 应该是 Up 或者 running。如果某个服务一直显示 Restarting 或 Exited,那大概率是配置或者资源问题。
更详细的日志排查方式是:
bash复制docker compose logs -f api
docker compose logs -f worker
首启过程中 db 容器会执行数据库初始化,如果 api 容器起来太早,可能会因为连不上数据库而报错退出。遇到这种情况不用慌,Dify 的容器重启策略会自动拉起,等待一小段时间后再查看状态即可。
我习惯在启动后等 1 到 2 分钟,让数据库迁移和初始化动作彻底完成,再打开浏览器访问。如果访问时页面空白或提示 502,先看 nginx 容器是否正常,再 ssh 到服务器上执行 docker compose ps 看看是不是有服务还处于 Starting 阶段。
3.4 首次登录与管理员账号设置
打开浏览器访问 http://localhost:18000 后,会进入管理员账号初始化页面。这里需要设置一个管理员邮箱和密码,这个账号以后是登录后台管理平台的入口。Dify 的管理员账号和普通应用账号是隔离的,这也是它面向多业务场景设计的一部分。
设置完成后进入主界面,你会看到几个一级菜单:应用、知识库、工具、工作流等。第一次进来的建议是先随便创建一个“聊天助手”类型的应用,然后在提示词里写一句最简单的系统设定,比如“你是一个乐于助人的助手”,保存后右侧就出现一个对话窗口,输入“你好”测试连通性。
如果选择的是在线模型,这一步需要提前在“设置—模型供应商”里填好 API Key。如果暂时没有在线模型 Key,可以先接本地 Ollama,这样完全不需要外网模型 API 也能跑通整个流程,下面一节细聊。
3.5 接入 Ollama 本地模型:解决“没有模型可用”的问题
很多朋友在 Dify 部署完以后卡在模型配置这一步,原因很简单:平台本身没有模型能力,你要先把模型供应商配置好,才能在应用里选用。如果你有 OpenAI 或国产大模型的 API Key,直接填到对应供应商页面即可。但如果没有 Key,或者你想完全在内网环境跑,Ollama 是一条性价比很高的路径。
Ollama 的安装非常轻量,一条 Docker 命令就能搞定:
bash复制docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
启动 Ollama 后,再去服务器或本机终端拉取一个模型,比如:
bash复制docker exec -it ollama ollama pull qwen2.5:7b
这里我特别提醒一下:默认 Ollama 只监听 127.0.0.1,如果你打算让 Dify 容器访问它,必须在启动 Ollama 时设置环境变量 OLLAMA_HOST=0.0.0.0,否则 Docker 里面的 Dify 即使知道你的宿主机 IP 也连不上模型服务。完整的启动命令是:
bash复制docker run -d -v ollama:/root/.ollama -p 11434:11434 -e OLLAMA_HOST=0.0.0.0 --name ollama ollama/ollama
然后回到 Dify 后台,在“设置—模型供应商”里找到 Ollama 并填写 Base URL。这里有一个容易踩坑的点:Dify 容器访问宿主机的时候,不能用 localhost 或 127.0.0.1,因为 Dify 容器内部是一个独立的网络环境。Windows 和 Mac 的 Docker Desktop 环境下可以用 http://host.docker.internal:11434,Linux 下我一般用 http://172.17.0.1:11434 或直接填宿主机局域网 IP。如果 Ollama 和 Dify 都在同一台机器上,这个地址填不对,模型列表就永远是空的。
填写完基础地址,Ollama 会自动把本地已经拉取过的模型同步到模型列表里。此时创建一个新应用,在模型选择里选 Ollama 的 qwen2.5:7b 或其他模型,就能直接对话了。
3.6 工作流与知识库:Dify 真正值钱的地方
应用跑通之后,我开始建议你不要只停留在对话界面,而是去看 Dify 的工作流和知识库模块。热词里经常出现“dify工作流搭建实例”,这个词不是营销概念,它确实是 Dify 核心生产力。
工作流的入口在应用编辑页面,你可以从“编排方式”里切换到工作流模式。Dify 的工作流节点包括开始、LLM、知识检索、代码执行、HTTP 请求、条件分支、模板转换等。我举个最小化例子:获取用户输入,用 LLM 节点做意图分类,如果用户问的是公司政策相关内容,就进入知识库检索分支,检索到的片段拼进提示词再让模型回答;如果不是,就走通用聊天分支。整个过程你在画布上连线完成,完全不用写接口。
知识库流水线的理解也很直观。知识库就是你上传文档后,Dify 自动切分、向量化、存储的场所。Dify 会把文档分割成片段,再用 Embedding 模型把每个片段向量化,检索时就拿用户的查询向量去向量数据库里匹配最相关的片段。我自己用下来觉得它的分段参数设置很关键,分段长度太长容易让向量语义模糊,太短又会丢失上下文。一般中文文档设置 200 到 500 个字符比较合适,重叠区域 50 到 100 字符,这样能保证检索命中率。
4. 升级、Windows 部署与常见故障排查实录
4.1 从社区版 1.10 看“多租户”和版本升级
Dify 社区版的更新节奏比较快,热词里出现“dify社区版1.10多租户”。多租户这个概念简单说就是一个 Dify 实例可以同时支持多个独立工作空间,工作空间之间数据、应用、成员是隔离的。这对团队内部使用非常有价值,你不用为了两个团队分别部署两套 Dify,只需要在同一个实例里创建两个工作空间,各自的模型配置和知识库互相不干扰。
不过我要提醒一句:创建多租户空间和管理成员需要管理员权限,而且空间创建时要绑定模型供应商或者按空间分配 Key。如果你只是自己个人使用,一个默认空间就够了,不必急着开通所有租户功能。
社区版的版本升级流程我实测下来算是比较顺畅的。在 docker 目录下按顺序执行:
bash复制docker compose down
docker compose pull
docker compose up -d
有一点必须先做:备份。虽然 Dify 把数据都存在了 Docker 卷里,容器重建并不会自动清空卷,但谨慎起见,升级前最好把数据库导出一份。PostgreSQL 的备份可以这样执行:
bash复制docker compose exec db pg_dump -U postgres -d dify > dify_backup_$(date +%Y%m%d).sql
如果你以前是拿旧版本跑过一段时间,里面有真实用户数据和知识库,升级前一定要看官方 Release Notes,关注是否有破坏性变更。跨大版本升级时,比如从 0.x 升到 1.x,一般会涉及数据库表结构调整,Dify 的 db 容器迁移脚本会自动处理,但迁移过程中不要手动启停服务,否则容易造成数据库锁表。
4.2 Windows 下 Docker Desktop 虚拟化启动失败的修复
“docker desktop failed to start because virtualisation support wasn't detected” 这个报错我帮人排查过很多次。字面意思是“没有检测到虚拟化支持”,但它不一定代表你的 CPU 不支持虚拟化,更多时候是 BIOS 没开启或者 Windows 系统的相关功能没启用。
第一步先去任务管理器—性能—CPU 里看右下角“虚拟化”状态是“已启用”还是“已禁用”。如果显示已禁用,那就要重启电脑进 BIOS 设置,在 CPU Configuration 或者 Advanced 菜单里找到 Intel Virtualization Technology 或 AMD SVM 的选项,改成 Enabled 保存退出。这一步不同的主板设置路径不同,但关键词通常就是 Virtualization、VT-x、SVM。
如果 BIOS 已经开了虚拟化,但 Docker Desktop 依然报同样的错,那问题大多出在 Windows 的 Hyper-V 或 WSL2 功能没有完整启用。Windows 10 2004 及以上版本,我会建议优先使用 WSL2 后端。执行前用管理员身份打开 PowerShell:
powershell复制wsl --install
安装完成后重启电脑,再打开 Docker Desktop,在 Settings 里确认 Use the WSL 2 based engine 这个选项是勾选状态。另外,Windows 的“内核隔离—内存完整性”和“基于虚拟化的安全”也可能干扰 Docker Desktop 启动,如果你看到报错信息里带有 Hyper-V 字样,可以临时关掉内核隔离试一试。
Docker Desktop 正常启动后,建议把资源限制也顺手调整一下。Docker Desktop 默认给 WSL2 分配的内存可能不够 Dify 全家桶跑,在 Settings—Resources 里把内存调到 6GB 或 8GB 比较合适,否则即使 Dify 容器正常启动,跑知识库向量化时也可能因为内存不足被系统杀掉。
4.3 容器常见故障与排查命令速查
我在部署 Dify 过程中遇到的故障基本可以归成三类:端口冲突、数据库连接失败、内存不足。这里整理一张速查表方便你对照处理:
| 现象 | 可能原因 | 排查命令 | 解决办法 |
|---|---|---|---|
| nginx 或 api 启动后反复重启 | 端口被占用 | docker compose ps / netstat -ano | 修改 .env 里 EXPOSE_NGINX_PORT 避开占用端口,重新 up |
| api 容器报错 can't connect to postgres | db 没起来或连接串不对 | docker compose logs api | 等待 db 初始化完成;检查 .env 中 DB_ 配置 |
| 页面能打开但接口请求失败 | URL 配置没跟着端口改 | 查看浏览器开发者工具 Network | 同步修改 CONSOLE_API_URL、APP_API_URL 等地址 |
| 容器全部启动但应用响应极慢 | 内存不足频繁 GC | docker stats | 停止多余容器,调高 Docker 内存限制 |
| docker pull 卡住 | 镜像加速源失效 | docker pull 一个测试镜像 | 更换 registry-mirrors 地址,重启 Docker |
还有一个我个人觉得非常实用的命令组合,服务异常时先看容器状态,再看日志,最后查资源:
bash复制docker compose ps
docker compose logs --tail=200 <service_name>
docker stats
这套流程能覆盖八成以上的启动问题。如果是 api 或 worker 日志里出现很长的 Python Traceback,建议直接把日志末尾内容粘到搜索框里找,很多坑都是前人踩过的,比盲改配置高效得多。
4.4 如果你想让 Dify 更接近生产环境
本地部署跑通之后,有些人会想着让它更稳定一点。我的经验是可以从三个方向优化。第一个是把默认的 SQLite 或本地默认组件换成性能更强的外部组件,但这部分和部署架构强相关,需要你理解 Dify 的存储设计后再动手。第二个是给 Nginx 配置 HTTPS 证书并关掉不必要的调试端口,让外部访问走加密通道。第三个是定期备份 volumes 里的数据,尤其是 pg 数据和上传文件目录,Dify 的管理后台本身提供导出功能,但底层的数据备份更稳妥。
不过我也要泼一盆冷水:任何平台投入到生产环境前,都要先跑至少一两周的试用,观察它在你自己的业务场景下是否稳定。不要因为部署成功就立刻说上线,生产环境要面对的东西比部署复杂得多。
5. 我在部署过程中收获的一些实际经验
整套部署过程走了几次弯路之后,我自己总结了三条比较受用的经验。
第一,Dify 这类开源平台在部署上其实没有那么难,难的是环境差异带来的未知问题。同样是 docker compose up,在干净的 Ubuntu 上和在 Windows Docker Desktop 上遇到的问题完全不一样。建议新手先把环境停留在你能控制的范围内,比如先用一台 Linux 虚拟机或云服务器练手,不要在 Windows 上一边配 Docker 一边调网络,容易把问题混淆。
第二,.env 文件里的配置项要敬畏。每次改动端口或者域名之后,不能只改一个值,要沿着 Nginx 端口、前端 URL、后端 URL 这条链路整体查看。我有一次就是只改了 EXPOSE_NGINX_PORT 却忘了改 APP_WEB_URL,结果控制台能打开,但应用分享出来的链接全是错的,排查了很久才发现。
第三,镜像拉取慢的问题不要一上来就怀疑 Dify,先用 hello-world 或 busybox 测试一下 Docker 自身的拉取链路。我调试过的案例里,有一半是镜像加速配置没生效,有四分之一是网络本身不稳定,剩下的才是服务器磁盘空间不够导致镜像下载后写不进去。先做最小化验证,能省下大量排查时间。
最后再分享一个小技巧:第一次部署前,先把 docker/docker-compose.yaml 打开扫一遍,看它依赖了哪些镜像 tag,然后手动 docker pull 这些镜像。这样可以避免 docker compose up 过程中因为多个镜像并发拉取导致网络阻塞。镜像齐了之后,Dify 整个启动过程通常不会超过三分钟。
