简介:想自建个人知识库的开发者或技术爱好者,可以从这份doc教程中获得一条完整的本地部署链路:ollama负责管理并运行deepseek模型,docker承载Dify项目,Dify完成知识库搭建与聊天界面,最终实现基于本地大模型的私有化知识问答。资源包为5.19MB,仅含1个doc文档,适合以图文步骤手册的形式边看边操作。文档从ollama官网下载、环境变量设置、模型拉取,讲到docker-desktop安装、Dify源码运行、docker compose启动服务,再到浏览器登录、创建知识库、连接ollama接口并选择deepseek模型,逐步说明关键配置与验证方法,对初学者常见的“命令不关闭”“端口地址填写”等细节也有提醒。按文档顺序操作,可以在Windows环境下完成从模型下载、接口接入到知识库问答的完整闭环,适合具备基本命令行操作能力、需要本地化部署知识库的用户。目前已有3389人学习下载,可作为搭建私有知识问答环境的直观参考。
1. deepseek 部署个人知识库,为什么是 ollama+deepseek+docker+Dify 这一套
deepseek 部署个人知识库,这件事真正难的不是“装一个大模型”,而是把文档切分、向量化、召回、大模型生成四个环节串成一条完整的 RAG 链路。过去我自己拼过一版,文档入库、问答接口、前端全要手写,一个环节出问题整条链就哑火,最后才换成 ollama+deepseek+docker+Dify 这套组合。它有四个不可替代的定位:ollama 把模型变成本地可直接调用的服务,deepseek 负责看懂上下文并生成答案,docker 固定整套运行环境,Dify 把知识库管理、检索配置、对话应用全部打包成可视化界面。
这套方案解决的是“文档留在本机、效果可验证、成本可控”的私有知识库需求,适合有一定 Docker 基础、不想手写 RAG 代码的开发者;也适合先花一个下午跑通最小闭环,再决定要不要往深做的团队。别指望它开箱即用,真正会卡住你的往往不是模型,而是容器网络、模型冷启动、检索参数这三个不起眼的细节,下面按顺序把这套部署讲透。
2. 先拆组件:ollama、deepseek、docker、Dify 各自在 RAG 里干了什么
2.1 ollama 把模型变成“本地服务”,是整条链的推理底座
本地知识库的第一步不是训练,而是把模型包装成一个本机可以随时调用的 HTTP 服务,这个活由 ollama 干。它本质上是一套模型运行时:负责模型文件下载、量化加载、显存调度,并对外暴露一个默认跑在 11434 端口的接口。你不需要为它搭建 Python 环境,不需要手动编译推理框架,也不需要自己写显存换入换出的逻辑。一条ollama run命令就能把模型拉下来,再通过 API 调用,对上层应用来说就是一个“本地模型网关”。
我见过不少同学把 ollama 当成聊天玩具,实际上它在整条 RAG 链里承担的是最底层的模型服务角色。Dify 不直接碰模型文件,它只负责向 ollama 发请求;ollama 也不关心你问的是知识库还是闲聊,它只负责把模型的推理结果返回。这种解耦的好处是:你想换 deepseek 的不同尺寸,只需要在 ollama 里换模型名,Dify 那边的供应商配置不用大改。
用 ollama 而不是直接用推理框架,还有一层现实原因:本地个人机器显存普遍有限,手动管理量化模型很容易翻车。ollama 默认按 4-bit 量化加载模型,显存不够时会自动借内存慢跑,至少保证整个流程能走得通。对“先验证再调优”的思路来说,这比一开始就折腾 GPU 加速要实际得多。
2.2 deepseek 负责生成,但知识库召回还得靠 embedding 模型
RAG 流程里真正会用到两个模型。deepseek 负责“看到召回的文档片段,组织成自然语言答案”,这是用户能直接感知的部分;但知识库能回答对,前提是文档被正确切分并向量化——做这件事的是 embedding 模型。提问时,问题也会被转成向量,和库里已有的向量做相似度计算,召回最相关的几个片段,最后才交给 deepseek 结合上下文生成答案。
所以部署阶段至少要在 ollama 里准备两个模型:一个是 deepseek 主模型,一个是 embedding 向量模型。主模型的选择直接决定回答质量和资源占用,给一张我常用的选型参考:
| 模型标签 | 角色 | 资源门槛参考 | 适用场景 |
|---|---|---|---|
| deepseek-r1:7b | 生成答案 | 约 6GB 显存,16G 内存可慢跑 | 个人知识库优先验证,显存小的主流选择 |
| deepseek-r1:14b | 生成答案 | 约 10GB 以上显存 | 有一张 12G 以上显卡,效果明显更好 |
| nomic-embed-text | 文档向量化 | 文件不到 300MB | 默认首选,中英文混合文档表现稳定 |
| bge-m3 | 文档向量化 | 文件在 1GB 上下 | 中文文档占比高时替换它,召回更准 |
这里的“显存”只是参考线,实际占用取决于量化档位和上下文长度,ollama 默认 4-bit 量化,显存不足时会借用内存,所以没有独显也能跑 7b,只是速度慢一些。个人做知识库验证,我一般建议从 7b 起步,先把链路跑通再谈换大模型。32b 以上不是不能跑,但内存和显卡要求直接翻倍,对多数人来说性价比很低。
2.3 docker 在整套方案里是“环境隔离层”,也是出问题后的后悔药
Dify 不是单进程应用,它依赖 PostgreSQL、Redis、向量数据库、API 服务、Worker 异步任务、Web 前端,底层还带一个代码执行沙箱。手工把这些组件装齐,系统级依赖冲突足够折腾一整天。用 docker compose 拉起整套编排,服务间的网络、依赖顺序、重启策略都预设好了,这正是 docker 在这套组合里的真正价值:它不是“部署平台”,而是环境隔离层。
对个人部署来说,docker 还有一个容易被忽略但极其实用的特性:重来成本极低。配置改坏了,docker compose down再up,几十秒回到干净状态,不会把宿主机环境搞得一团糟。这也是我坚持用 docker 跑 Dify 而不是直接源码安装的原因——出了问题有后悔药可吃。
但 docker 也带来一个典型的新手陷阱:容器网络隔离。Dify 跑在容器里,它访问宿主机上的 ollama 时,localhost指向 Dify 容器自己,并不是宿主机。这个问题在 3.3 和避坑章节会专门展开,这里先把结论记住:Dify 里填 ollama 地址,要填宿主机 IP,不能填 127.0.0.1。
3. ollama 上跑起 deepseek 与 embedding 模型:安装、拉取与监听配置
3.1 安装 ollama 并确定模型目录
Linux 和 macOS 上最省事的方式是官方一键脚本,Windows 则是下载安装包后直接跑。这里以 Linux 原生安装为例,执行安装脚本后,ollama 的 CLI 和后台服务会一并装好,不需要手动管守护进程:
curl -fsSL https://ollama.com/install.sh | sh安装完成后先别急着拉模型。建议想清楚模型文件放哪个目录,ollama 默认把模型放在用户主目录的隐藏目录下,如果你的系统盘不大,拉两三个模型就吃满磁盘了。我一般会把它指向数据盘或独立分区:
mkdir -p /data/ollama/models cat > /etc/systemd/system/ollama.service.d/override.conf <<'EOF' [Service] Environment="OLLAMA_MODELS=/data/ollama/models" Environment="OLLAMA_HOST=0.0.0.0:11434" EOF systemctl daemon-reload systemctl restart ollama这段配置做了两件事:OLLAMA_MODELS把模型存储位置改到数据盘,避免系统盘被塞满;OLLAMA_HOST=0.0.0.0:11434让 ollama 监听所有网卡地址,这是后续 Dify 容器能访问它的前提。如果没有 systemd 环境,可以用export OLLAMA_MODELS=/data/ollama/models && ollama serve代替。另外,如果你打算用 docker 方式跑 ollama,环境变量要写进 compose 文件,端口映射要写成0.0.0.0:11434:11434,不能只映射到回环地址。
3.2 拉取 deepseek 与 embedding 两个模型并自测接口
模型存储位置就绪后,拉取主模型和向量模型。我把 deepseek-r1:7b 和 nomic-embed-text 一起拉,前者负责问答生成,后者负责知识库的文档向量化:
ollama pull deepseek-r1:7b ollama pull nomic-embed-text ollama list ollama show deepseek-r1:7bollama list用来确认两个模型都已就绪,ollama show可以查看模型参数量和量化方式,判断资源占用是否符合预期。这里有个容易踩的细节:Dify 配置模型时填的模型名必须和ollama list里显示的完全一致,大小写、后缀都不能差。
模型就绪后用一条 curl 自测接口,确认 ollama 的推理链路是通的,再往下配置 Dify 就不会出现“模型没问题但界面报错”的困惑:
curl http://127.0.0.1:11434/api/generate \ -d '{"model": "deepseek-r1:7b", "prompt": "用一句话介绍RAG", "stream": false}'这条请求的关键参数是model,值必须和ollama list里的名字一致;stream: false表示一次性返回完整结果,方便在终端确认输出。正常会返回一段 JSON,response字段就是模型生成的内容。如果这里直接报错,看ollama serve的前台日志,显存不足、模型文件损坏都会在这里留下具体提示。
3.3 让 ollama 监听容器能访问的地址
ollama 默认只监听127.0.0.1,这在本地 curl 没问题,但 Dify 跑在 docker 容器里,容器访问宿主机的回环地址是不通的。所以必须把监听地址放开,这就是 3.1 里设置OLLAMA_HOST=0.0.0.0:11434的原因。
监听配置改完后,不要急着去 Dify 里填地址,先在宿主机上做两步验证:
curl http://127.0.0.1:11434/api/version curl http://192.168.1.10:11434/api/version第二条里的 IP 要换成你自己机器的局域网地址,用ip addr或系统网络设置查看。第一条通、第二条不通,说明OLLAMA_HOST没生效或防火墙拦了;两条都通,说明监听没问题。这一步排查在部署里极其重要,能帮你把“Dify 配置问题”和“ollama 网络问题”明确切开。
有一点需要说明:Docker Desktop 环境下 Dify 配置里填host.docker.internal可以直接访问宿主机,但在 Linux 原生 docker 环境下这个域名不一定可用。为了部署教程的通用性,后续统一用宿主机局域网 IP 作为 ollama 地址,这是最不容易翻车的做法。
4. docker 拉起 Dify:最小命令、三个必调参数与知识库串通
4.1 拿到 docker 编排并改三个必改项
Dify 的发布包里带着完整的 docker 编排目录,包含 compose 文件和.env.example环境变量模板。拿到后进入docker子目录,先把配置模板复制成实际配置:
cd dify/docker cp .env.example .env打开.env,第一次部署我不建议大改,只动三处。第一是 Web 端口,默认值经常被本机其他服务占用,我习惯改成高位端口;第二是数据库密码,默认值太弱,跑在可联网机器上有风险;第三是确认向量存储类型保持默认,这是整套编排里最不容易出错的默认值。
以下是三个必改项的定位:
| 配置项 | 推荐做法 | 说明 |
|---|---|---|
| EXPOSE_NGINX_PORT | 改成 8080 之类不冲突的端口 | 前端入口,冲突会导致 Web 页面打不开 |
| POSTGRES_PASSWORD | 换成自己的强密码 | 数据库连接串会自动引用它 |
| VECTOR_STORE | 保持默认即可 | 首次部署不要动,跑通再考虑换 |
改完先别急着up,检查一下docker目录下是否存在 compose 文件,确认无误再启动。.env是整套编排的变量总入口,nginx、api、worker、数据库都会读取它,所以端口改动在.env里完成,而不是去改 compose 文件。
4.2 启动服务并确认后端日志正常
编排就绪后启动整个服务栈,Dify 会同时拉起 Web 前端、后端 API、异步 Worker、PostgreSQL、Redis、向量数据库等多个容器:
docker compose up -d docker compose psup -d是后台启动,第一次会拉取镜像,耗时取决于网络和镜像体积,耐心等它完成。docker compose ps用来查看各容器状态,重点关注是不是所有服务都进入running或healthy状态;如果有容器一直Restarting,不要急着往下配置,先看日志:
docker compose logs -f apiapi是后端主进程,配置错误、数据库连不上都会在这里报错。worker负责异步任务,知识库文档的向量化就是它处理的,后面文档一直“处理中”时也要回头看它的日志。等api和worker日志稳定、没有 ERROR 堆栈,再打开浏览器访问 Web 页面。
提示:看到容器状态为 Restarting 时不要继续配置模型供应商,先解决日志里的具体报错。容器反复重启通常指向数据库未就绪或 .env 配置有误。
4.3 在 Dify 添加 Ollama 供应商与系统模型
浏览器打开http://宿主机IP:8080,首次访问会进入管理员初始化页面,填一个邮箱和密码即可。完成初始化后,在设置里找到模型供应商,选择 Ollama。这里注意:Dify 界面里可能已经有默认提示,但地址一定要按下面的原则填:
| 配置项 | 推荐值 | 为什么 |
|---|---|---|
| API 地址 | http://宿主机局域网IP:11434 | 容器访问 127.0.0.1 指向的是 Dify 自己 |
| 模型名称 | deepseek-r1:7b | 必须和 ollama list 完全一致 |
| 模型类型 | LLM | 生成答案用 |
保存后先做连通性测试,通过后再进入“系统模型”设置。系统模型里有两个关键位置必须手动指定:默认推理模型选 deepseek-r1:7b,Embedding 模型选 nomic-embed-text。如果只配了提供商、没配系统模型,知识库的向量化和对话生成就可能走了默认占位,出现“文档传了但回答完全不相关”的情况。
这里有一个值得强调的坑:如果 ollama 和 Dify 都在同一台机器上,Dify 容器里不能写http://localhost:11434,因为 localhost 是 Dify 容器自己。填宿主机局域网 IP 是最通用的做法。如果机器改了局域网 IP,回到这个页面改一下地址即可,不用动 docker。
4.4 建知识库、设分段与检索参数,串起第一个问答
模型供应商就绪后开始建知识库。上传一份包含明确事实内容的文档,比如产品说明书、项目接口文档,格式用 PDF、TXT、Markdown 都可以。上传后进入分段设置,这是影响召回效果的第一个关键参数:
| 参数 | 推荐配置 | 作用 |
|---|---|---|
| 分段长度 | 约 500 字符 | 太长则召回粒度粗,太短则上下文被切断 |
| 分段重叠 | 约 100 字符 | 避免完整句子被截断在两段之间 |
| 索引方式 | 高质量 / 向量索引 | 向量召回,本地知识库的标准选择 |
| 召回模式 | 混合检索 | 兼顾关键词和语义 |
| TopK | 3 到 5 | 召回片段太少答案容易落空 |
| Score 阈值 | 0.2 起调 | 阈值太高会把相关片段全过滤掉 |
为什么要加段落重叠?因为切分是硬切,一句话可能正好横跨两个分段,召回时只看其中一段会觉得信息不完整,重叠部分能起到缓冲作用。为什么要从 0.2 起步调 Score 阈值?本地 embedding 模型的向量得分普遍不会像云端大模型那么高,设 0.5 会把相关文档全滤掉,表现为“知识库失忆”。0.2 起调,之后根据召回测试结果慢慢往上抬。
文档处理完成后,进入应用页面创建一个对话型应用,在编排页的“上下文”里关联刚建好的知识库,提示词里写明“优先依据知识库内容回答”。保存后发一条与文档内容直接相关的问题,比如文档里明确写过的安装步骤、参数要求。如果回答里带了引用来源,说明整条 RAG 链路已经打通,这就是最小闭环。
5. 部署避坑:四个常见的运行时翻车现场
5.1 ollama 一直连接失败,先查监听地址和容器网络而不是重装
现象:Dify 添加 Ollama 供应商时反复提示连接失败,docker compose logs api里出现connection refused。很多人第一反应是重装 ollama,其实问题基本不在模型上。
原因有两个:一是 Dify 容器里的127.0.0.1是 Dify 自己,不是宿主机;二是 ollama 的OLLAMA_HOST没有设置成0.0.0.0,默认只监听回环地址,容器根本访问不到。
解决思路按两步排查走:
curl http://127.0.0.1:11434/api/version curl http://192.168.1.10:11434/api/version第一条通、第二条不通,说明 ollama 监听地址没放开或防火墙拦截;两条都通,问题就出在 Dify 界面上填的 IP 不对。改完监听地址后别忘重启 ollama 服务。A 同学当初就是两条 curl 没跑,直接在界面里换了五个 IP 硬试,浪费了半天。
5.2 第一次提问等到超时,是模型冷启动不是死机
现象:第一次提问要等几十秒,甚至直接超时;连续问第二句就明显变快。如果每次都慢,则是显存不足导致模型反复换入换出。
原因:ollama 默认模型加载后一段时间不活跃就会卸载,下次请求要重新从磁盘加载到显存;embedding 模型和 deepseek 如果都在 ollama 上,知识库问答时会先加载向量模型再加载生成模型,首次请求自然慢。
解决思路分两步。第一步先执行一次ollama run deepseek-r1:7b手动预热,确认模型能正常加载。第二步让它常驻:
# Linux systemd 环境下追加环境变量 cat > /etc/systemd/system/ollama.service.d/override.conf <<'EOF' [Service] Environment="OLLAMA_KEEP_ALIVE=-1" EOF systemctl daemon-reload systemctl restart ollama这个参数的含义是模型加载后一直驻留内存,避免反复冷启动。代价是显存和内存会被模型持续占用,如果机器资源紧张,可以不设成-1,而是设成较长的时间,比如30m。资源极有限时,干脆把模型换回 7b,比调各种缓存参数都见效。
5.3 知识库建好了,回答却“失忆”,问题多在 Embedding 和检索参数
现象:文档里明明写了“系统要求 8GB 内存”,问“内存要求多少”答不上来,或者回答内容通篇是模型自己的常识,完全没有引用文档。
原因:最常见的是系统模型里的 Embedding 没配置,或者配置了但没生效,文档向量化走了错误通道;其次是检索参数太严——TopK 太小、Score 阈值太高,相关片段在召回阶段就被过滤掉了;还有一种情况是分段设置不合理,答案信息正好被切到两个分段里。
解决思路按顺序来:先确认“设置 → 系统模型”里的 Embedding 模型是 nomic-embed-text;再到知识库页面里对单条文档做“召回测试”,输入同样的问题看能否召回对应片段。召回测试结果为 0,基本可以断定 Embedding 配置或文档向量化出了问题;召回正常但答案没用,就要改提示词,明确要求“优先依据知识库回答,不要使用常识作答”。这两个问题不分开排查,很容易陷入反复调参的循环。
5.4 端口冲突、容器反复重启、向量化排队,先看日志再判断
现象:docker compose ps里某个容器一直Restarting,或者 Web 页面打不开,或者上传文档后一直停在“处理中”。
原因:Web 端口被占用导致前端容器起不来;.env里的数据库配置改了但相关服务没完全重启;向量化任务在 CPU 上排队,文档长、切分块数多,处理慢是正常的;如果一直卡住,多数是 embedding 模型地址不对,Worker 反复请求失败。
解决思路只有一个:看日志再行动。
docker compose logs -f api docker compose logs -f workerapi报端口或数据库错误,回去查.env对应项;worker报 embedding 请求失败,回到第 3 章的 curl 验证步骤重新确认 ollama 地址。向量化慢不算故障,把分段长度调大到 800 到 1000,块数少了处理速度会明显提升。日志是这套组合里最可靠的排查入口,比到处猜配置管用得多。
6. 验证 RAG 效果与两个进阶方向:从“能跑”到“敢用”
最小闭环跑通只代表链路通了,不代表回答可靠。我习惯给知识库准备 30 个文档内事实问题,逐个问一遍,重点看回答里是否带引用来源、引用是否指向正确段落。回答没引用,说明召回可能为空;引用错段,说明分段或检索参数需要调。这个验证过程不难,但能筛掉绝大多数“看起来能用”的假象。
进阶方向一是把 Dify 应用接入自己的工具链。Dify 的应用页面会生成 API 密钥,拿到后用 curl 就能调用:
curl -X POST http://localhost:8080/v1/chat-messages \ -H "Authorization: Bearer app-xxxxx" \ -H "Content-Type: application/json" \ -d '{"inputs":{},"query":"安装文档里要求的备份步骤是什么?","response_mode":"blocking","user":"tester"}'这里的Authorization填 Dify 应用密钥,query是问题内容,response_mode: blocking表示等待完整结果返回,适合排查。返回里的answer字段是最终回答,citations字段能看到引用的知识库片段,这两个字段是判断 RAG 是否真正生效的直接证据。
进阶方向二是按效果瓶颈做升级。文档先做清洗和结构整理,按章节拆分文件,这比调任何参数都见效;中文文档占比高时,把 embedding 换成 bge-m3,召回准确率会有可感知的提升;如果引用经常不够精确,给 Dify 配一个 Rerank 模型,在混合检索后做一次精排,TopK 保留 3 条最相关的片段,回答质量会再上一个台阶。
我第一次搭这套组合时,图省事地址全填 localhost,卡在“模型已拉好、Dify 连不上”的状态一下午,后来用 curl 从宿主机 IP 通了一次才发现是容器网络的事。从那以后,凡是 docker 里的服务,我都会先跑一条 curl 验证网络再配界面,这个习惯帮我少踩了很多坑。希望帮到你。
本文还有配套的精品资源,点击获取