简介:面向需要将大模型能力安全落地到企业内部的技术团队,这份幕僚云私有化部署Dify+Ollama+DeepSeek-R1资源包,提供了一套从零开始的一体化部署方案。Dify承担应用编排与数据集管理,Ollama负责本地化模型运行,DeepSeek-R1作为推理引擎,三者协同可实现隐私保护下的数据分析与智能决策。包内共36个文件,包含30张关键部署步骤截图(png),覆盖环境检查、镜像加载、服务启动等环节;同时提供Docker离线安装包、docker-compose编排文件、Docker配置模板,以及配套PDF操作说明,整体压缩包约97.99MB,目录结构清晰,便于按阶段对照实施。无论是初次接触私有化部署的运维人员,还是需要快速复现大模型平台的架构师,都能从这套资料中获取完整的落地思路与配置参考。资源中的配置与截图来自实际部署项目,可大幅缩短部署周期、降低试错成本。目前该资源已有4763人学习下载,是一份高价值的实战参考。
1. 幕僚云要的是私有化:Dify+Ollama+DeepSeek-r1到底解决了什么
把 Dify、Ollama、DeepSeek-r1 串起来做私有化部署,本质上是要在不让数据出内网的前提下,拿到一套能跑知识库问答、工作流自动化和 Agent 任务的完整大模型平台。Dify 负责应用编排和前端交互,Ollama 负责把模型跑在本地 GPU 或 CPU 上,DeepSeek-r1 负责实际生成内容。适合谁?要么是企业在意的数据合规,要么是你不想按 token 付费、想把模型调用成本变成一次性硬件投入。这套组合已经是企业大模型私有化部署里最常见的落地路径,Dify 社区版 + Ollama 的本地部署教程满天飞,但真正能稳定跑上生产的,还得看你怎么规划拓扑、怎么配模型供应商、怎么处理上下文超长和并发。
2. 部署拓扑与选型:先定 Ollama 的机器和模型档位,再谈 Dify 接入
2.1 为什么是 DeepSeek-r1:量化档位与显存/内存规划
DeepSeek-r1 不是单指某个 671B 的庞然大物,Ollama 仓库里那一串deepseek-r1:7b、deepseek-r1:14b、deepseek-r1:32b、deepseek-r1:70b都是蒸馏版本。选哪个档位,取决于你的显卡显存和业务对回答质量的要求。很多人上来就拉 70b,结果一张 A100 都放不下,最后卡到没法用。
我的习惯是先算显存账。Ollama 里模型的量化档位直接决定内存占用,Q4_K_M 是默认,质量损失小、资源占用适中。7b Q4 大概需要 5~6GB 显存,14b 要 10~12GB,32b 要 20GB 以上,70b 至少 40GB 起步,还得给 KV cache 留余量。如果你只有一张 24GB 的 3090/4090,14b 是安全选择,32b 会很勉强。没有 GPU 只靠 CPU 跑也不是不行,内存 64GB 以上跑 14b Q4,生成速度大概每秒两三 token,做内部知识库问答能忍,做对话机器人就有点痛苦。
还有一个容易被忽略的点:DeepSeek-r1 是推理模型,默认会在输出前生成一段“思考过程”。在 Ollama 里跑ollama run deepseek-r1:14b问个简单问题,你会看到一串分析再给结论,这在技术演示时很炫,但在正式业务里会拖慢响应、浪费 token。后面接入 Dify 之后,我一般会在模型参数里把温度调低、关掉推理过程输出,或者干脆用deepseek-r1:14b之外的小参数模型处理简单分类任务。
2.2 搭一个最小可用的 Ollama 服务:离线安装包与模型存储路径
Ollama 的安装看起来简单,一条curl -fsSL https://ollama.com/install.sh | sh就完事,但你在内网环境里大概率会遇到下载慢或者直接超时。ollama 下载太慢了是热词里出现频率最高的问题,实际操作我建议走两条路:一条是找一台能联网的机器先把安装包和模型文件拉下来,再拷进内网;另一条是配置代理或换镜像源。
离线安装的常见做法是先在有网的机器上下载 Ollama 的二进制压缩包,解压后把ollama可执行文件放到/usr/local/bin/,再自己写一个 systemd 服务来管理。模型文件更麻烦一点,ollama pull deepseek-r1:14b会从 registry 拉取分层的 blob,默认存在~/.ollama/models或/usr/share/ollama/.ollama/models。如果你想把模型存到别的盘,用环境变量OLLAMA_MODELS指定路径,比如:
# 在 systemd service 里指定模型存储路径 sudo mkdir -p /data/ollama/models sudo tee /etc/systemd/system/ollama.service <<'EOF' [Unit] Description=Ollama Service After=network-online.target [Service] Type=simple Environment="OLLAMA_MODELS=/data/ollama/models" Environment="OLLAMA_HOST=0.0.0.0" Environment="OLLAMA_KEEP_ALIVE=24h" ExecStart=/usr/local/bin/ollama serve Restart=always RestartSec=3 [Install] WantedBy=default.target EOF sudo systemctl daemon-reload sudo systemctl enable --now ollama这里有两个参数值得说。OLLAMA_HOST=0.0.0.0是让 Ollama 监听所有网卡,Dify 部署在另一台机器时才能访问;如果你只在本机跑,改成127.0.0.1更安全。OLLAMA_KEEP_ALIVE=24h是模型在显存里的驻留时间,默认 5 分钟就卸载,频繁调用时每次都要重新加载,慢得离谱。设成 24h 或更长,能让小团队在白天工作时段内几乎无感。
2.3 拉取模型时的三个选择:量化版本、下载慢、校验
ollama pull deepseek-r1:14b这个命令很多人以为版本号只有一个,实际上你可以指定量化档位,比如deepseek-r1:14b-q4_K_M。不指定的情况下默认是 Q4_K_M,但如果你内存紧张,也可以考虑 Q3_K_S,生成质量会差一点,换来的是内存占用更低。
下载慢这个问题,除了离线搬运,还有一个更优雅的办法:在能联网的机器上ollama pull完,直接把整个~/.ollama/models目录打包,拷贝到内网机器上再启动。要注意的是,模型目录打包后,目标机器的OLLAMA_MODELS要指到解压后的路径,否则它会重新去 registry 拉。还有一次我把模型目录拷过去之后忘了校验文件完整性,结果ollama serve时报 manifest 解析失败,用ollama list能看到名字,但一跑就报错。解决办法是删掉~/.ollama/models/manifests/registry.ollama.ai下对应的 manifest 文件,重新 pull 一次,或者干脆重新解压备份包。
# 查看已缓存的模型 ollama list # 查看模型详细信息和量化档位 ollama show deepseek-r1:14b --modelfile # 手动测试接口是否通 curl http://127.0.0.1:11434/api/generate -d '{ "model": "deepseek-r1:14b", "prompt": "你好,用一句话介绍你自己", "stream": false }'ollama show --modelfile能让你看清这个模型背后的 Modelfile 里写了什么参数,比如temperature、top_p、num_ctx。num_ctx是上下文窗口长度,默认 2048,这个值太小,后续接 Dify 知识库时会频繁触发上下文超长问题。我一般在 Modelfile 里手动拉长到 8192 或 16384,代价是显存占用上涨,但长文档问答的体验会好很多。
3. 把 Dify 接到 Ollama 上去:模型供应商配置与 SSL/认证排错
3.1 Dify 的模型供应商怎么填:Base URL、API Key 与 Ollama 协议
Dify 支持把 Ollama 作为模型供应商加进去,填的地方在「设置 → 模型供应商 → Ollama」。这里有两个关键字段:Base URL和API Key。Ollama 原生 API 是不需要鉴权的,但 Dify 的模型供应商表单里 API Key 是必填项,常见做法是随便填一个非空字符串,比如ollama,Dify 不会实际校验它。如果你在 Dify 里看到An error occurred during credentials validation,多半不是 Key 的问题,而是 Dify 根本访问不到 Ollama 的接口。
Base URL 怎么填取决于你的部署形态。同一台机器上跑 Dify 和 Ollama,填http://127.0.0.1:11434就行;分开部署就填 Ollama 所在机器的内网 IP,比如http://192.168.1.20:11434。这里有个最容易踩的坑:Dify 如果用 Docker Compose 部署,容器内部的127.0.0.1不是宿主机,所以你会看到 Dify 容器里访问http://127.0.0.1:11434永远超时。正确做法是用host.docker.internal(仅限 Docker Desktop)或宿主机的内网 IP。
# docker-compose.yaml 里给 Dify API 容器加 extra_hosts services: api: extra_hosts: - "host.docker.internal:host-gateway"这一行加完,Dify 容器里就能用http://host.docker.internal:11434访问宿主机的 Ollama。如果你是 Linux 裸机部署 Dify,不用 Docker,那就没有这个问题,直接填127.0.0.1即可。
3.2 credentials validation 失败与 dify ssl 错误的排查路径
An error occurred during credentials validation是 Dify 里最经典的报错,几乎每个接 Ollama 的人都遇到过。这个报错背后是 Dify 在保存供应商配置时,会向 Ollama 发一个测试请求来验证连通性。验证失败的原因分四层:
第一层,网络不通。检查 Dify 容器和 Ollama 之间能不能telnet通,docker exec -it dify-api-1 curl http://host.docker.internal:11434一下,如果 curl 报连接拒绝,先看 Ollama 的OLLAMA_HOST和防火墙。第二层,协议不匹配。Dify 的 Ollama 供应商要求 Base URL 末尾不要带多余路径,直接到/就行,填成http://ip:11434/v1反而会让验证请求 404。第三层,API Key 为空。Dify 的表单校验会拦截空 Key,但填了假的 Key 之后,Ollama 并不校验,所以只要能通就行。第四层,SSL 问题。
dify ssl错误这个热词,实际上有两种情况。一种是你给 Dify 前端配了 HTTPS,但 OLLAMA 还是裸 HTTP,Dify 浏览器端访问时出现混合内容报错;另一种是你用 nginx 给 Ollama 加了 TLS,证书链不完整导致 curl 校验失败。多数小团队没必要给内网 Ollama 上 TLS,但如果你非要上,记住 Ollama 原生不支持 HTTPS,只能用 nginx 反向代理来做。证书要是自签的,Dify 那边的验证会直接失败,因为 Java/Node 的默认信任库不认自签证书。
nginx 反向代理 ollama 设置 apikey这个场景我也处理过。用 nginx 把http://ip:11434代理到一个带 TLS 的域名,顺便在server块里加auth_basic或一个自定义头的校验。配置大概长这样:
server { listen 443 ssl; server_name ollama.internal.example.com; ssl_certificate /etc/nginx/ssl/ollama.crt; ssl_certificate_key /etc/nginx/ssl/ollama.key; location / { proxy_pass http://127.0.0.1:11434; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 简单用 Header 做访问控制 if ($http_x_ollama_token != "your-token-here") { return 403; } } }这种配置的好处是 Dify 的 Base URL 直接填https://ollama.internal.example.com,API Key 填your-token-here,Ollama 自己不用改任何东西。但有一个坑:Ollama 的/api/generate是流式返回,nginx 默认会缓冲响应,导致 Dify 那边一直收不到第一帧,表现为“请求挂起”。需要加proxy_buffering off;和proxy_read_timeout 300s;才能让流式输出正常。
3.3 Dify 社区版的模型类型:对话、补全与 Rerank
Dify 接入 Ollama 后,模型类型要选对。Ollama 供应商在 Dify 里支持三种类型:对话模型(LLM)、 embedding 模型、 rerank 模型。DeepSeek-r1 是对话模型,填进去之后在应用里选它的名字就行。但如果你要跑知识库,还得单独挂一个 embedding 模型。常见做法是用 Ollama 跑nomic-embed-text或bge-m3,同样走本地,价格为零,但检索质量会直接影响问答效果。
embedding 模型选好之后,Dify 的知识库会做两件事:文档分段和向量化。分段长度默认是 500 个字符,重叠 50,这个参数需要根据你的文档类型调。合同、制度这类长段落文档,分段太短会把上下文拆碎,回答时引用不完整;分段太长又会让向量检索的精度下降。我一般从 300 试到 800,看测试集上的召回效果再定。
4. 知识库与工作流里的 DeepSeek-r1:上下文超长的处理与流水线
4.1 知识库流水线的选型:retrieval、重排序与向量库
Dify 的知识库流水线不只是“文档上传 → 切割 → 向量化 → 检索”这么简单。真正影响问答质量的是检索之后的流程:向量检索召回 TopK 条,然后如果你配了 rerank 模型,再做一次精细化排序;没有 rerank 的话,直接靠向量相似度排序,经常会出现“看起来相关但实际答非所问”的情况。
weknora dify热词说明很多人已经在聊 WeKnora 这类增强检索组件,但多数私有化部署项目不会一上来就上重型检索服务。Dify 内置的检索模式有向量检索、全文检索和混合检索,对 90% 的内部知识库场景,混合检索就够了。我一般把 TopK 设为 3~5,Score 阈值设为 0.3~0.5,防止无关片段混进来。向量库方面,Dify 默认支持weaviate、qdrant、milvus和pgvector,小规模部署用weaviate或qdrant最省心,容器起来就有;大规模再用milvus。
dify知识库排队中这个状态很多人都遇到过。现象是文档上传后一直显示“排队中”,不进入索引状态。原因多半是 embedding 模型没配好,或者向量库连接不稳定。Dify 处理知识库文档是异步任务,队列消费失败后状态就卡住。可以先到 Dify 的后台日志里看 worker 容器有没有报错,最常见的错误是 embedding 接口超时,Ollama 那边模型加载太慢。
# 查 Dify worker 容器的日志 docker logs dify-worker-1 --tail 200 | grep -i "error\|embedding" # 手动验证 embedding 模型是否可用 curl http://host.docker.internal:11434/api/embeddings -d '{ "model": "bge-m3", "prompt": "测试文本" }'如果 embedding 接口本身是通的但很慢,多半是 Ollama 每次都要重新加载 embedding 模型,OLLAMA_KEEP_ALIVE设置太短。也有可能是 Dify 配置的 embedding 模型名在 Ollama 里不存在,比如你填了bge-m3:latest,但实际 pull 的是bge-m3,名字不完全匹配,接口 404,任务就会一直重试直到超时。
4.2 工作流上下文超长怎么办:记忆窗口、分段与引用压缩
dify工作流 上下文超长是接入 DeepSeek-r1 后立刻会碰到的硬问题。R1 是推理模型,输入 prompt 里塞一大堆历史消息、检索片段和工具结果之后,它会先思考一遍,原来的上下文窗口很快就不够用。这里有三层应对。
第一层,模型侧把num_ctx拉大,比如 16384。但要注意,拉大 num_ctx 不只是显存问题,DeepSeek-r1 对长上下文的推理速度会明显变慢。第二层,Dify 应用侧控制对话历史。Dify 的对话应用有“记忆窗口”设置,把它从默认的 20 轮降到 4~6 轮,就能大幅削减输入 token。如果是要处理超长文档问答,推荐用“知识库检索增强”而不是把全文塞给模型。第三层,Dify 工作流里可以对检索结果做引用压缩,比如只保留每条检索片段的前 500 字,或者用 LLM 节点先把检索片段做一次摘要,再拼进最终 prompt。
dify 工作流本身是个很灵活的东西,但很多人上来就把工作流画得很复杂,结果每个节点都在往上下文里塞东西。我见过一个实际案例:一个包含 8 个节点的知识库问答工作流,每个节点都输出完整文档片段,到最后一个 LLM 节点时,prompt 已经超过 3 万 token。这种做法在云端大模型上只是费钱,在本地推理模型上直接就是慢和卡。我的原则是:本地部署的 R1,工作流里尽量让每个节点输出最小必要信息,中间过程用变量覆盖而不是追加。
# Dify 工作流里 LLM 节点的一个推荐参数设置(示意) model: deepseek-r1:14b temperature: 0.3 max_tokens: 2048 context: memory_window: 6 retrieval_top_k: 4 retrieval_score_threshold: 0.4这段不是可粘贴的配置文件,但参数思路值得抄:温度 0.3 是为了让 R1 少一些发散,毕竟知识库问答要的是稳定;max_tokens 2048 是因为大多数业务问题的答案不需要长篇大论,设小了也防止它把“思考过程”当正文输出。
5. 私有化部署的坑:下载慢、段错误、迁移与并发排查
5.1 现象:ollama 下载太慢,乃至一个模型拉了两天
原因:Ollama 默认从registry.ollama.ai拉模型,国内网络访问这个域名经常被限速,一个 14b 模型 Q4 量化文件大小约 9GB,卡在几 KB/s 很正常。
解决:先在有强网络的机器上拉好,然后离线搬运;或者配置镜像源。Ollama 支持在启动时设置OLLAMA_REGISTRIES,但各版本支持度不一样,最稳妥的还是离线包。把整个~/.ollama/models目录打成 tar 包,传到内网机器解压,设置好OLLAMA_MODELS指向它。注意 tar 打包时要保留符号链接,模型 manifest 文件是硬链接结构,打漏了会导致ollama list能看到但 run 不了。
5.2 现象:ollama serve 段错误,服务一启动就崩
原因:这个属于玄学问题,但绝大多数时候和 CUDA 版本、GPU 驱动有关系。Ollama 自带的运行时对老显卡的兼容并不完美,我遇到过一次是在 T4 上跑得好好的,换到另一台有 P40 的机器上直接 segment fault。
解决:先ollama serve前台跑,看崩溃时的错误输出;如果是 CUDA 相关的 init 报错,试着装新一点的 NVIDIA 驱动,或者设置CUDA_VISIBLE_DEVICES只留一张卡。排除了 GPU 问题之后,再检查内存条,Ollama 在加载大模型时要分配大量连续内存,内存不稳定也会段错误。再有就是模型文件损坏,重新ollama pull覆盖一次。
5.3 现象:Dify 迁移之后模型供应商全部失效
原因:Dify 的配置存在 PostgreSQL 里,迁移时如果只搬了容器的数据卷,没搬数据库,或者搬了数据库但外部向量库的地址没更新,模型供应商配置就全部断掉。
解决:Dify 社区版迁移要搬三样东西:PostgreSQL 数据、Redis 数据(对话会话缓存)、向量库数据。常见做法是docker compose down之后,直接复制volumes目录到新机器。但要注意,用docker compose cp是没法搬的,直接用文件系统层面的rsync更可靠。新机器上部署好之后,如果模型供应商还是报错,去 Dify 后台重新保存一次配置就行,多数情况下只是连接地址里的 IP 变了。
5.4 现象:多个用户同时用,响应越来越慢,甚至排队
原因:Ollama 默认是单机串行处理,多个请求同时进来会排队,每个请求都要占显存。Dify 那边如果设了OLLAMA_KEEP_ALIVE太短,模型反复卸载加载,性能更差。
解决:先给 Ollama 加并发限制意识——它自己不会限制,全靠 GPU 显存兜底。14b Q4 在 24GB 卡上大概只能同时跑 2 个请求,超过之后即使有两个请求也在抢显存。短期的办法是OLLAMA_NUM_PARALLEL=2,配合OLLAMA_MAX_LOADED_MODELS=1,让它同一时间只加载一个模型。长期还是要根据团队规模上多卡,或者把模型档位降到 7b。Dify 侧的 worker 数量也要调,docker compose里dify-worker的副本数从 1 加到 2,但 OLLAMA 后端性能上不去的话,加 worker 不会提高并发质量,只会把任务推到同一个瓶颈上。
6. 让这套部署长期稳定运行的几个技巧与收尾
6.1 用环境变量和健康检查把服务管起来
前面 systemd 管理 Ollama 是一种方式,但如果 Dify 和 Ollama 都在 Docker 里,我更喜欢在 compose 文件里统一加健康检查。Ollama 虽然没有官方的 /healthz,但用/api/tags探测就可以:
services: ollama: image: ollama/ollama:latest container_name: ollama volumes: - /data/ollama/models:/root/.ollama environment: - OLLAMA_HOST=0.0.0.0 - OLLAMA_KEEP_ALIVE=24h - OLLAMA_NUM_PARALLEL=2 ports: - "11434:11434" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"] interval: 30s timeout: 5s retries: 3这段 compose 配置在实际项目中帮我省了不少事。OLLAMA_KEEP_ALIVE=24h避免频繁重载模型,OLLAMA_NUM_PARALLEL=2让两个请求可以并发,healthcheck配合 Docker 的自动重启策略,能在服务假死时自动恢复。
6.2 升级前先停 Dify,再动 Ollama
Dify 社区版的升级是个反复出现的痛点。Dify 的docker compose升级脚本会拉新镜像、迁移数据库,但如果你同时还在跑 Ollama,模型加载状态不受影响,不过 Dify 的 API 容器重启会断掉所有正在进行的会话。我的顺序是:先docker compose downDify 全家桶,确保没有正在跑的任务;再升级 Dify;最后确认模型供应商配置没丢,才开始让业务流量进来。Ollama 这边升级没那么频繁,如果 Ollama 版本太老和 Dify 新版不兼容,通常表现是调用接口时 404,先ollama --version确认版本,然后重新拉最新版二进制。
6.3 一个我几乎忘掉的教训
接入 Dify 后第一次给业务方演示时,我用 DeepSeek-r1 跑一个“总结本月运营数据”的对话,结果 R1 先思考了四十多秒,输出了一长串分析过程,最后才给结论。现场体验非常糟糕。后来我养成了一个习惯:凡是直接面向用户的对话应用,要么关掉思考过程输出,要么选用非推理模型处理这类指令式问题,把 R1 留给复杂推理和深度问答。另外一件事是,我差点把整个模型目录放在系统盘根分区,等磁盘写满才发现Ollama的模型缓存和日志会把盘撑爆。后来我在/data/ollama/models和 Docker 的data目录上都挂了一块独立数据盘,并且加了一个定期清理日志的 cron。私有化部署这件事,模型能不能跑起来只是第一关,真正决定能不能长期运营的,是磁盘、内存、并发这些“土”问题。希望帮到你。
本文还有配套的精品资源,点击获取