今年开源大模型这一波是真的热闹,DeepSeek、Qwen、Llama 轮番刷榜,身边不少朋友都往自己电脑上装 Ollama 跑本地模型。但绝大多数人跑完就卡住了——模型是能聊了,可要做成真正能用的 AI 应用,还得考虑知识库、工作流编排、Agent 工具调用这些事,总不能全靠手写代码。我自己的做法是用 Dify 这个开源的 LLM 应用开发平台,把模型、知识库、工作流全部串起来,直接在网页上拖拽配置。这篇文章记录的就是我在 Windows 环境下,用 Docker 把 Dify 完整部署起来的过程,包括环境准备、容器启动、接入本地 Ollama 模型跑通第一个应用的每一个步骤,以及一路上踩过的坑和排查思路。如果你手里正好是一台 Windows 电脑,又想搞一套能本地跑的 AI 应用平台,这篇文章可以直接照着抄。
1. 在 Windows 上部署 Dify 到底图什么
先说清楚一件事:Dify 不是什么“模型本身”,而是一个大语言模型应用的开发与运营平台。你可以把它理解成一个 AI 应用的“操作系统”——模型只是发动机,Dify 负责把方向盘、仪表盘、底盘全部装好。它能帮你把 Hugging Face、Ollama、OpenAI 等各种模型源接进来,然后通过可视化的工作流编排、知识库检索(RAG)、Agent 工具调用、Prompt 调试这些能力,快速搭出一个真正能回答业务问题的 AI 应用,而不是只有“你好,我是 AI 助手”这种聊天框。
1.1 当“本地跑大模型”变成“本地开发 AI 应用”
单跑一个模型很容易,Ollama 装完,ollama run deepseek-r1 一行命令就能聊起来。但真实场景里没人只想要一个聊天框。我举个实际例子:你手上有一套内部产品文档,想做一个“文档问答机器人”。这里面至少有四件事是模型本身做不了的:
- 文档得切成块、做向量化,存进向量数据库,回答问题时先检索再生成
- 对话历史要管理,不然上下文一长模型就“失忆”
- 用户问法五花八门,可能需要先做意图识别,再分流给不同 Prompt
- 回答完最好还能带来源引用,方便人核对
这些事情如果全部从零写代码,光数据管道和前端界面就得折腾一两周。而 Dify 把这些能力全部图形化了,知识库上传文档、配置检索参数、拖拽一个“问题分类 + 知识检索 + LLM 回答”的工作流,半小时能跑通第一版。
1.2 为什么选 Docker 而不是直接装服务
Dify 不是单进程应用,它后端有 API 服务、Worker 异步任务、Web 前端,还要依赖 PostgreSQL、Redis、向量数据库(Weaviate 或其他)、Sandbox 沙箱等一大堆组件。手动一个个装,光版本兼容性就能让人崩溃。我有一次为了折腾类似的东西,光装 PostgreSQL 就花了一个晚上处理 Windows 下的权限问题。
Docker 的价值在于把整个依赖环境全部塞进容器里。Dify 官方提供了编排好的 docker compose 文件,里面把每个组件的镜像、端口、环境变量、网络关系全部定义好了。你只要执行一条 docker compose up -d,Docker 会自动拉取所有镜像、创建内部网络、启动全部服务。Windows 上跑 Docker 用的是 WSL2 后端,本质是个轻量级 Linux 虚拟机,所以和 Linux 服务器上的行为高度一致,排错经验可以直接迁移。
1.3 适合哪些人看这篇
这篇东西适合三类人:一是想在本地把 Dify 跑起来、跟着教程做 AI 应用开发的开发者;二是团队里想快速搭一个内部 AI 平台做 PoC(概念验证),但又不想第一轮就花钱上云的小团队;三是已经在 Linux 上部署过 Dify、现在换到 Windows 环境一时搞不定 Docker Desktop 的运维同学。如果你是这三类人之一,后面的内容应该能帮你省下不少时间。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Docker Desktop 安装:最容易劝退的一关
很多人在部署 Dify 之前就被卡死了,原因不是 Dify 本身,而是 Docker Desktop 压根启动不了。Windows 上跑 Docker 依赖 WSL2 或者 Hyper-V,而这俩又依赖 CPU 虚拟化。我见过太多人卡在 “Virtualization support not detected” 这个报错上,所以把这一关单独拿出来说。
2.1 先搞定 WSL2
新版 Windows 10/11 装 WSL2 已经很简单了,用管理员权限打开 PowerShell,执行:
bash复制wsl --install
这条命令会自动启用 WSL 功能、安装默认的 Ubuntu 发行版,并在支持的情况下把 WSL 版本设置为 2。装完以后按提示重启电脑。重启后可以验证一下:
bash复制wsl -l -v
正常会看到类似这样的输出:
code复制 NAME STATE VERSION
* Ubuntu Running 2
如果 VERSION 显示是 1,说明当前发行版用的还是 WSL1,需要手动转换:
bash复制wsl --set-version Ubuntu 2
2.2 虚拟化检测失败的完整排查
Docker Desktop 启动时报 “virtualization support not detected” 是最典型的难题。这个报错的本质是:Docker Desktop 在启动 WSL2 后端时,发现 CPU 虚拟化没有被启用。一般就三个原因:
| 可能原因 | 检查方法 | 解决办法 |
|---|---|---|
| BIOS 里没开虚拟化 | 任务管理器 → 性能 → CPU → 左下角看“虚拟化”是否显示“已启用” | 进 BIOS,找到 Intel VT-x 或 AMD-V 选项并开启 |
| Windows 的虚拟化相关功能没启用 | PowerShell 执行 systeminfo,看 Hyper-V 要求相关行 |
执行 bcdedit /set hypervisorlaunchtype auto 后重启 |
| 杀毒软件/安全策略拦截 | 看 Docker Desktop 日志是否有权限相关错误 | 在 Windows 安全中心中检查内核隔离设置,必要时关闭内核隔离 |
我自己碰到的情况是 BIOS 里 Virtualization Technology 被关了。这个选项在 Intel 主板上通常叫 “Intel Virtualization Technology” 或 “VT-x”,在 AMD 主板上叫 “SVM Mode”,不同品牌主板的 BIOS 菜单位置不一样,但搜 “Virtualization” 一般都能找到。开启后保存重启,Docker Desktop 就能正常起来了。
2.3 给 WSL2 设置资源上限
这块是纯经验之谈。Docker Desktop 默认会吃 WSL2 虚拟机的内存,而 WSL2 的默认配置是把物理内存的 50% 或者更多分给虚拟机。如果你电脑是 16GB 内存,跑完 Dify 那十几个容器后,Windows 本机可能会明显卡顿。
解决办法是手动创建一个 .wslconfig 文件来控制 WSL2 的资源占用。在 C:\Users\你的用户名 目录下新建 .wslconfig,内容参考:
ini复制[wsl2]
memory=8GB
processors=4
swap=2GB
localhostforwarding=true
改完以后在 PowerShell 里执行 wsl --shutdown 让配置生效。重启 Docker Desktop 后,WSL2 的内存上限就被限制在 8GB 了。这里我不建议你把内存设得太小,Dify 全家桶加一个本地模型推理,内存低于 6GB 会很吃力。
3. 拆解 Dify 的一键部署原理
Dify 的“一键部署”听起来很玄,实际上就是它把一套复杂的分布式应用架构做成了标准化的容器编排配置。搞懂它在编排什么,后面出了问题你才知道去哪里看日志。
3.1 docker compose 文件里到底编排了哪些服务
Dify 的 docker/docker-compose.yaml 文件里,默认启用的服务大概有这些:
| 服务名 | 作用 | 说明 |
|---|---|---|
| api | Dify 后端 API 服务 | 核心业务逻辑,Flask 应用 |
| worker | 异步任务处理 | 处理文档索引、知识库切分等耗时任务,基于 Celery |
| web | 前端页面 | 浏览器访问的界面 |
| db | PostgreSQL 数据库 | 存用户、应用配置等关系型数据 |
| redis | 缓存与队列 | 存储会话状态、异步消息 |
| weaviate | 向量数据库 | 知识库的向量检索 |
| sandbox | 代码执行沙箱 | 执行工作流里的代码节点,隔离运行环境 |
| ssrf_proxy | HTTP 代理 | 防止服务端请求伪造,安全组件 |
| nginx | 反向代理 | 统一入口,转发到 api 和 web |
| plugin_daemon | 插件守护进程 | 管理插件市场与安装 |
这些容器由 Docker Compose 自动创建了一个内部网络,互相之间通过服务名通信。api 容器要访问数据库,直接用 db:5432 这样的地址就行了,不需要知道数据库的 IP。这也是容器编排比手工装服务的最大优势——整个依赖拓扑是声明式的,写死在配置文件里。
3.2 选对版本:社区版、企业版与版本号
Dify 有云服务版和社区版。社区版是开源的,可以自己部署,这个版本一直在迭代。我写这篇的时候,社区版已经到 1.x 系列,较新的版本里还加入了多租户能力,意味着一个部署实例能服务团队里多个人,各自的数据、应用互相隔离。这对小团队来说是很大的便利,以前要各自搭一套,现在只需一套。
版本选择上,我建议直接用官方 GitHub Releases 里的最新稳定版,而不是 main 分支。main 分支是开发版,可能包含未充分测试的功能。我会在下一步讲怎么固定版本号,避免拉下来一个“半成品”。
3.3 配置文件不是随便改的
Dify 目录下会有一个 .env.example 文件,部署前要复制一份成 .env。这个文件里全是环境变量,包括各类密钥、端口、数据库密码等。它的作用相当于给所有容器注入配置,容器启动时读取这些值来动态改写自己的配置。所以改完 .env 以后必须重启容器才生效,光改文件是没用的。
注意 .env 文件里的 SECRET_KEY 和数据库密码,生产环境一定不能留默认值,否则很容易被扫描工具攻击。虽然本地开发随便点无所谓,但如果你打算让团队共同使用,这条一定要认真对待。
4. 完整部署:从拉取源码到所有容器就绪
接下来进入正戏。以下所有命令都在 PowerShell 或 Windows Terminal 里执行,前提是 Docker Desktop 已经启动,并且能正常运行 docker ps。
4.1 获取 Dify 源码
Dify 的部署配置都在 GitHub 仓库里,不需要把整个代码库下载下来,只要 docker 目录下的编排文件就够了。最稳的方式是 clone 指定版本:
bash复制git clone --branch 1.10.0 --depth 1 https://github.com/langgenius/dify.git
--branch 指定版本号,--depth 1 表示只拉最新一次提交,省时间也省空间。如果你不确定哪个版本号最新,就去 GitHub Releases 页面看,挑带 Latest 标签的那个。我写这篇时用 1.10 系列是比较稳的。
然后用终端进入到 docker 目录:
bash复制cd dify/docker
4.2 修改 .env 的必改项和常见端口冲突
在 docker 目录下,把示例环境变量文件复制成正式的 .env:
bash复制cp .env.example .env
Windows 的 PowerShell 下 cp 是 alias,指向 Copy-Item,用法一样,没问题。复制完以后用编辑器打开 .env(VS Code 就行),有三个地方我建议改一下:
第一处是端口。
ini复制EXPOSE_NGINX_PORT=80
Dify 默认通过 80 端口访问。80 是 HTTP 默认端口,经常被 IIS、Apache 或者其他软件占用。如果 80 被占用,启动后 nginx 容器会起不来,报端口冲突。我习惯改成 8080:
ini复制EXPOSE_NGINX_PORT=8080
第二处是密钥。
ini复制SECRET_KEY=请替换成一长串随机字符串
可以用 PowerShell 生成一个随机字符串:
powershell复制-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 50 | ForEach-Object {[char]$_})
第三处是数据库密码。
ini复制POSTGRES_PASSWORD=difyai123456
POSTGRES_DB=dify
POSTGRES_USER=postgres
改成你自己的强密码。其他的环境变量先保持默认,等部署成功后可以再按需调整。
4.3 启动容器并等待健康检查
配置改好后,直接执行:
bash复制docker compose up -d
这里有个细节:首次执行会拉取十几个镜像,加上基础镜像总共可能有几个 GB,耗时取决于网络状况。如果你发现拉取速度慢,可以在 Docker Desktop 的 Settings → Docker Engine 里配置国内可访问的镜像源,也就是 registry-mirrors,配完保存重启动 Docker Desktop 再重新执行命令。
容器启动后,通过 docker compose ps 查看状态:
bash复制docker compose ps
正常情况所有服务的 STATUS 列应该显示 Up(运行中)。但刚启动的几分钟内,部分服务可能还在初始化,比如数据库正在做首次初始化、api 在等数据库就绪,所以 STATUS 可能出现 (healthy) 之前的过渡状态。给点耐心,等五分钟再看。
想确认所有服务是否“健康”,可以看 nginx 服务是否变成 healthy:
bash复制docker compose ps | Select-String nginx
如果看到 nginx 显示 Up (healthy),恭喜你,整个平台已经服务就绪了。
4.4 验证容器间的联通性
服务起了不代表业务通,我习惯额外做一步验证。进入 api 容器,尝试连接数据库:
bash复制docker compose exec api python -c "import psycopg2; conn=psycopg2.connect(host='db', port=5432, user='postgres', password='你的密码', dbname='dify'); print('db ok')"
这条命令如果输出 db ok,说明 api 容器能正常访问数据库容器,整个内部网络是通的。
5. 首次登录与平台初始化
Dify 部署完成后,第一次使用前要设置管理员账号,这一步走完才算真正激活。
5.1 创建管理员账号
浏览器访问 http://localhost:8080(端口就是你改的 EXPOSE_NGINX_PORT),会自动跳转到管理员初始化页面,让你设置邮箱和密码。这里有几个我实测下来的注意点:
- 邮箱不需要是真实邮箱,不验证,填个自己记得住的就行
- 密码建议设置得复杂点,因为管理员权限很大,能管理所有应用和成员
- 设置完以后会自动登录,并进入欢迎页面
以后要进入管理后台,路径是在右上角头像菜单里选“设置”,可以看到成员管理、模型供应商、插件管理、数据源等入口。如果你部署的是带多租户的新版本,这里还能看到租户管理的选项。
5.2 平台三个核心模块怎么理解
首次进入 Dify 主界面,左侧有“应用”、“知识库”、“工具”三大块,我的理解是这样:
- 知识库:把文档上传进去,Dify 会自动切块、做向量化。后面做问答应用时,勾选知识库检索,应用就能基于文档内容回答,这是 RAG 的核心载体。
- 应用:一个应用就是一个 AI Bot 的完整配置,包括用哪个模型、走什么工作流、挂哪个知识库、用什么 Prompt。可以发布成 Web App、嵌入网页或者调 API。
- 工具:给 Agent 用的外部能力,比如搜索、计算器、HTTP 请求。工作流里的 Agent 节点可以自动决定调用哪个工具来完成任务。
这三个模块搭起来就是一套完整 AI 应用的骨架。初期你可以先建一个最简单的“聊天助手”应用,什么都不挂,喂给模型一个 Prompt 就能跑,感受一下前后端交互。
5.3 在线升级的正确姿势
Dify 社区版迭代很快,升级本身不复杂,核心逻辑是拉新镜像、重建容器、数据留在数据卷里。我升级过好几次,完整步骤是这样:
bash复制# 1. 进入 docker 目录
cd dify/docker
# 2. 备份当前 .env(以防万一)
cp .env .env.bak
# 3. 拉取仓库最新代码
git pull
# 4. 拉取最新的镜像
docker compose pull
# 5. 基于新镜像重建容器
docker compose up -d
关键是数据都在具名数据卷(volume)里,重建容器不会删数据卷,所以 PostgreSQL 里的用户、知识库、应用配置都还在。升级后如果发现页面异常,先执行 docker compose logs -f api 看日志,再决定是否需要回滚。我备份 .env 的习惯,就是为了在升级失败时能快速还原配置。
6. 接上 Ollama:跑通第一个本地模型应用
到这里,Dify 平台是跑起来了,但它只是一个“空壳子”,还没接任何大模型。我要把 Ollama 里跑的本地模型接进来,让 Dify 真正能用。
6.1 Windows 上装 Ollama 并拉取模型
Ollama 是个极其好用的本地模型运行工具,官网直接下载 Windows 安装包,装完以后在终端里执行:
bash复制ollama pull deepseek-r1:7b
等进度条走完,模型就下载到本地了。想验证模型能不能正常推理:
bash复制ollama run deepseek-r1:7b
这里我说明一下,部署在 Windows 本机的 Ollama 监听的是宿主机(也就是 Windows 本身)的端口,Dify 的 api 容器要访问它,中间隔着一层 WSL2 虚拟机。这就是接下来的关键问题所在。
6.2 容器访问宿主机的关键细节
在 Dify 的“设置 → 模型供应商”里找到 Ollama,需要填一个 API 地址。很多人第一反应填 http://localhost:11434,然后测试连接报错,怎么试都不通。
原因在于:localhost 在容器内部指向的是容器自己,而不是你的宿主机 Windows。
Docker Desktop 会在 WSL2 里维护一个内部的地址,宿主机地址在容器里通常通过 host.docker.internal 来访问。所以 Ollama 的 API 地址要填:
code复制http://host.docker.internal:11434
填完之后点“测试连接”,才能通过。这个问题我在本地部署时卡了十几分钟,一开始还以为是防火墙问题,后来想起容器网络和宿主机网络的隔离原理才反应过来。这是 Windows + Docker + 本地模型这个组合最常见的坑,值得专门记一笔。
6.3 用 DeepSeek 建一个问答应用
模型配置好后,创建应用就完全是图形化操作了。在左侧“应用”里选“创建应用”,选择“聊天助手”,填个名字,然后在模型选择里选刚才配置的 Ollama 供应商,模型名填 deepseek-r1:7b。
此时直接在调试区域发一句“你好”,如果 Ollama 那边正常,Dify 会很快返回结果。到这里,你已经在本机成功跑通“Dify + 本地大模型”的完整链路了。
再进阶一步,你可以创建知识库,上传几个文档,然后在应用设置里打开“知识库”功能,勾选刚建的知识库。这样 Dify 会先检索知识库中与用户问题最相关的文档片段,再把片段拼进 Prompt 喂给本地模型,实现基于你私有文档的问答。这个流程全在网页上操作,没有写一行代码。
7. 实战踩坑记录与排查方法
部署过程不可能一帆风顺,我把自己踩过和看别人踩过的坑集中列一下。这些也是搜索引擎里关于 Dify 部署问得最多的问题。
7.1 端口被占用:最频繁的启动失败原因
如果你启动后在 docker compose ps 里看到 nginx 容器反复重启,大概率是端口被本机其他程序占了。排查方法很简单,在 PowerShell 里执行:
bash复制netstat -ano | findstr :80
如果有输出,最后一列是占用进程的 PID,接着用:
bash复制tasklist | findstr PID号
看是哪个程序,然后决定是关掉那个程序,还是改 Dify 的 EXPOSE_NGINX_PORT 换个端口。我个人建议直接改端口,因为 80 端口被系统或者其他软件抢占的可能性太高了。
7.2 镜像拉取速度慢或超时
这个问题在国内网络环境下特别突出。Docker Hub 的镜像拉取经常慢到几 KB/s,甚至直接超时。配置 registry-mirrors 是官方支持的方式,在 Docker Desktop 的 Settings → Docker Engine 的 JSON 配置里加:
json复制{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerproxy.com"
]
}
保存后 Docker Desktop 会自动重启,然后重新执行 docker compose up -d。配置镜像源只影响拉取行为,不影响容器运行,放心用。
7.3 WSL2 内存暴涨导致电脑卡顿
Dify 全家桶占用的内存大头其实不在数据库,而是 API 服务和向量数据库,再加上 Ollama 本地模型推理也吃内存。16GB 内存的机器跑起来很容易飙到 90% 占用。
除了前面说的 .wslconfig 限制,还有一个实用经验:Ollama 的模型并发推理数量限制可以调低,默认情况下 Ollama 会一次性加载所有模型,改一下环境变量 OLLAMA_NUM_PARALLEL=1 能显著降低内存占用。
7.4 容器健康检查一直不通过
这种情况我遇到过两次,一次是数据库初始化慢,另一次是 API 容器依赖数据库但启动顺序没协调好。Docker Compose 虽然有 depends_on,但那只保证启动顺序,不代表前一个服务已经完全就绪。观察 api 的日志,如果反复出现数据库连接失败,说明它在等 db 初始化完成,等两分钟自己就会好。如果一直不好,就是数据库密码或者网络配置有问题了。
7.5 排查问题通用的三板斧
遇到任何容器问题,我的排查顺序固定是这三步:
docker compose ps看哪些服务没起来docker compose logs -f 服务名看具体报错(比如docker compose logs -f api)docker inspect 容器名看环境变量、网络配置是否符合预期
这套方法帮我解决过 90% 的部署问题。别一上来就卸载重装,先看日志,日志会告诉你绝大部分真相。
最后分享几个实战体会
整个部署走下来,我的最大感受是:Dify 本身的部署逻辑并不复杂,真正花时间的是 Windows 环境自身的不确定性——虚拟化没开、端口被占、WSL2 内存爆满,这些问题任何一个都能让你卡上一小时。但只要把环境基础打牢,后面几乎是一条命令的事。另外,强烈建议你在第一次部署时就用 .wslconfig 限制好资源,别想着“先跑起来再说”,等跑了一会儿发现电脑卡到鼠标都动不了再去收拾就晚了。部署完成后先不要急着加一堆插件和工作流,把“一个模型 + 一个最小应用”这条链路跑通,再逐步增加知识库、Agent、多租户这些能力。这样每一步出问题,都容易定位,不至于在复杂的配置里迷失方向。
