☰
Dify+Ollama+DeepSeek-r1 私有化部署实战:从架构选型到避坑指南
2026/9/25 23:09:01 网站建设 项目流程

简介:一套面向企业IT运维与技术人员的Dify+Ollama+DeepSeek-r1私有化部署资源包,聚焦数据安全与个性化服务场景,解决在隔离网络环境中搭建完整AI数据处理链路的需求。资源共36个文件,涵盖PDF部署手册、Docker离线安装包(docker-27.4.1.tgz)、docker-compose编排文件、系统服务配置以及30张关键步骤截图,总大小约97.99MB,可完整复现从环境初始化到组件联调的全过程。目前已有4760人学习下载。通过图文对照,读者能快速掌握Dify数据集成、Ollama模型服务与DeepSeek-r1推理引擎的私有化组合方案,理解系统需求分析、软硬件环境搭建、配置安装、集成测试与维护升级各环节要点;部署截图按时间顺序组织,可清晰还原每一步命令行操作与界面状态,大幅降低排错门槛。尤其适合需要在内网环境交付企业级AI平台的技术人员参考。

1. 幕僚云私有化部署:为什么是 Dify + Ollama + DeepSeek-r1 这套组合

做幕僚云这类偏内部使用的 AI 应用平台,私有化部署几乎是绕不开的诉求。数据不出内网、模型完全自持、工作流自己掌控,这几条每一条都直接决定方案选型。我推荐且反复验证过的一条路径是:用 Dify 做应用编排层,Ollama 做本地推理引擎,搭配 DeepSeek-r1 这类可私有化部署的推理模型。这样既不需要把业务数据送到外部 API,又能让业务团队直接在界面上拖拽搭建智能体应用,而不必每改一个提示词就去找开发改代码。整套东西跑在企业自己的服务器上,运维边界清晰,成本也可控。这篇笔记会把我实际部署时踩过的坑、参数设置和验证方式一次讲清楚。

2. 先搞懂三个角色各干什么:架构选型与能力边界

2.1 Dify 在幕僚云里的真正位置:不是模型,是应用工厂

很多人第一次接触 Dify,以为它是一个模型聚合网关。实际上 Dify 的核心定位是一个 LLMOps 平台,它解决的是“模型有了之后,怎么变成业务应用”的问题。在幕僚云这类场景里,你需要的往往不是一个聊天框,而是带知识库、带工作流、带权限管理的完整应用。Dify 提供的恰恰是这套东西:可视化工作流编排、知识库分段与检索、提示词管理、应用发布与 API 封装,以及多租户隔离能力。

我一般会把 Dify 比作“应用工厂”。它本身不生产模型能力,但它能把模型能力包装成业务团队可以直接使用的应用。Dify 社区版从 1.10 版本开始支持多租户,这一点对幕僚云这类面向多个内部团队或多家客户的服务来说很关键。以前做多租户要自己改代码,现在开箱即用,每个租户有自己的应用、数据集和 API Key,数据互相隔离。

在接入层,Dify 通过“供应商”机制对接各种模型来源。它有两条主流路径:一条是接外部 API(比如各类云厂商模型服务),另一条就是接本地推理服务。你要做私有化,后者才是重点——Dify 通过标准的 OpenAI 兼容接口对接 Ollama,Ollama 再负责加载和调度 DeepSeek-r1 模型。整条链路都跑在你自己的服务器上,不需要出网。

2.2 Ollama 不是一个简单启动器:它的运行机制决定了部署姿势

Ollama 在很多文章里被描述成“下载模型就能跑”,但它的实际工作方式有几个容易被忽略的点。首先,Ollama 是一个常驻服务,默认监听 11434 端口,它负责模型的拉取、加载、推理调度和生命周期管理。其次,模型文件存储在特定目录下(Linux 一般在 /usr/share/ollama/.ollama/models,macOS 在 ~/.ollama/models),这个目录可以在启动时通过 OLLAMA_MODELS 环境变量修改——这点在磁盘规划时非常重要。第三,Ollama 会根据你的显存大小自动选择加载方式,显存够就把模型全部放进 GPU,显存不足就自动切换到 CPU 推理并做部分卸载,但这样做性能下降明显。

对于幕僚云这种生产级私有化部署,我建议把 Ollama 当作一个独立的推理服务来运维,而不是把它当成本地调试工具。这意味着你要考虑它是否开机自启、日志怎么收集、模型加载了哪些、端口要不要暴露到内网、API 是否加了访问控制。这些在单机玩模型时没人管,但一旦接入 Dify 做业务,每一项都是稳定性问题。

2.3 DeepSeek-r1 的本地化身份:蒸馏版与实际可用形态

DeepSeek-r1 在开源社区的形态主要是一系列蒸馏模型。所谓蒸馏版,就是用完整的 R1 模型作为教师模型,把推理能力压缩到更小的参数量上。部署到本地时,常见的选择是 1.5B、7B、8B、14B 和 32B 这几个尺寸。这里要重点说一句:32B 和 14B 的体验差距是明显的,但硬件开销差距也是翻倍的。幕僚云如果只是做内部知识问答、流程审批辅助、文档摘要这类场景,7B 到 14B 的蒸馏版在效果和成本之间是比较均衡的区间。

Ollama 的模型仓库里有 DeepSeek-R1 系列,拉取命令是ollama pull deepseek-r1:7b或指定具体版本。需要注意,Ollama 上标注的 deepseek-r1 是量化打包后的格式,实际加载后的显存占用要看量化位数。生产环境建议用 Q4 或 Q5 量化版本,能在效果和资源占用之间取得平衡。如果你有 A100/H100 这类大显存卡,可以考虑直接跑完整版 R1,但那属于另一类部署方案,不在本文讨论范围内。

3. 离线内网环境下的准备:镜像传递、模型分发与目录规划

3.1 把 Dify 的 Docker 镜像完整离线化搬运

Dify 官方推荐用 Docker Compose 部署。但你面对的是幕僚云这类内网场景,往往意味着拉不了公网镜像。最常见的做法是在一台有外网权限的机器上先把镜像拉全,然后docker save打包,再拷贝到内网后用docker load导入。听起来简单,做起来有几个细节容易翻车。

先看 Compose 文件里到底需要哪些镜像。Dify 1.10 社区版的核心镜像大致包含:dify-api、dify-web、dify-nginx,以及依赖的 PostgreSQL、Redis、Weaviate 或 Qdrant(向量数据库)、Sandbox 等。我在实操时一般先把 compose.yaml 下载下来,然后直接解析其中的 image 字段,逐个拉取。

# 在有外网的机器上执行:解析并拉取全部镜像 docker compose -f docker-compose.yml config --images | while read img; do echo "Pulling $img ..." docker pull "$img" done # 全部拉完后打包。生产环境建议按镜像单独打包,避免单文件过大 docker save dify-api:latest -o dify-api.tar docker save dify-web:latest -o dify-web.tar docker save nginx:latest -o dify-nginx.tar docker save postgres:15-alpine -o postgres.tar docker save redis:6-alpine -o redis.tar docker save weaviate:1.19.0 -o weaviate.tar docker save langgenius/dify-sandbox:latest -o sandbox.tar

这里说明一下为什么建议单个镜像打包而不是一次性docker save全部打包:单镜像打包在目标机上可以并行加载,出问题时也好定位是哪一个镜像损坏。另外docker save出来的 tar 会保留镜像的层级信息,内网机器docker load后不会丢失标签。如果内网机器数量多,我建议再搭一个本地 Registry(比如 Harbor),把镜像推送到内网仓库里,各服务器直接从内网仓库拉取,比传 tar 包高效得多。

参数方面的关键点:docker compose config --images这个命令会解析出 compose 文件里定义的所有镜像完整名称,包括依赖镜像。如果你的 Compose 文件里用了.env文件控制镜像标签(比如DIFY_IMAGE_TAG),需要先确保.env已经被正确加载,否则config命令可能解析出默认版本。

3.2 Ollama 模型的内网分发:从有网机器到离线服务器

Ollama 拉模型慢是广为人知的痛点,在只做内网部署的环境下更是如此。我的做法是“两步走”:先在开发机上ollama pull,再把模型文件整体拷贝到内网服务器。不要尝试在 Ollama 服务启动后通过修改环境变量切模型目录——直接操作模型文件目录最可靠。

# 第一步:在开发机上拉取所需模型 ollama pull deepseek-r1:7b ollama pull deepseek-r1:14b # 第二步:查看模型实际存储位置 ollama list # 找到 MODELS 目录,一般在 ~/.ollama/models 或 /usr/share/ollama/.ollama/models # 第三步:压缩整个 models 目录 tar -czf ollama-models.tar.gz ~/.ollama/models # 第四步:拷贝到内网服务器后解压到指定位置 tar -xzf ollama-models.tar.gz -C /usr/share/ollama/.ollama/ # 第五步:重启 Ollama 并验证 systemctl restart ollama ollama list

这里有一个很容易忽略的地方:Ollama 服务启动时的用户和 HOME 环境变量决定了它找模型目录的路径。如果用 systemd 管理,启动用户是ollama,它的 HOME 是/usr/share/ollama,模型目录就是/usr/share/ollama/.ollama/models。但如果你直接手动执行ollama serve且当前用户是 root,它会去/root/.ollama/models找。这两种情况下ollama list的结果可能完全不同。解决办法是在 systemd 服务文件里显式设置Environment=OLLAMA_MODELS=/data/ollama/models,把模型目录固定在一个你规划好的大分区上。

我踩过的一个坑就是:默认放在系统盘,结果模型越拉越多,把根分区塞满了。幕僚云如果规划多个模型版本,建议至少预留 200GB 以上的独立数据盘给 Ollama。一个 14B 的 Q4 量化模型大约在 9GB 左右,但加上 embedding 模型、备用版本、日志预留,空间消耗会很快超预期。

3.3 Embedding 模型:Dify 知识库的隐藏依赖,但 Ollama 也扛得住

幕僚云这类应用几乎必然要开知识库功能,而知识库的向量化离不开 embedding 模型。Dify 的知识库流水线第一步就是把文档切成小块并向量化。如果只配了对话模型,没有 embedding 模型,知识库无法正常工作。

embedding 模型同样可以用 Ollama 加载,选型上我常用bge-m3或者shaw/dmeta-embedding-zh。这两种对中文支持都还可以,其中 bge-m3 在检索任务上更稳。拉取方式并无二致:

ollama pull bge-m3

但要注意一个关键配置:Dify 在接入 Ollama 时,embedding 模型和对话模型可以来自同一个 Ollama 实例,但 Dify 会把 embedding 模型的“上下文长度”按 512 token 处理。如果你的文档分段超过了这个长度,要么在 Dify 的知识库设置里调整分段长度,要么选择上下文更长的 embedding 模型。我在幕僚云项目里通常把分段长度设置在 300 到 500 字之间,既能保证检索粒度,又不会触发 embedding 长度超限。

4. 让 Dify 与 Ollama 真正对话:对接配置、模型接入与工作流挂载

4.1 把 Ollama 作为 Dify 模型供应商:一张参数表说清楚

Dify 的管理后台里,“设置 → 模型供应商 → Ollama”是你要操作的位置。这里的核心参数不多,但每一个都踩过坑。

参数推荐值说明
API Base URLhttp://host.docker.internal:11434或http://<宿主机IP>:11434不能写localhost,因为 Dify 跑在容器里,localhost 指向容器自身
Model TypeLLM / Embedding 分别配置同一个 Ollama 实例可以同时提供对话和向量化能力
Model Namedeepseek-r1:7b或bge-m3必须与ollama list里的名称完全一致
上下文长度按模型实际支持设置写太大会导致超限截断,写太小浪费能力

这里最常出问题的就是 API Base URL。Dify 的 api 容器要访问宿主机上的 Ollama,在 Linux 上可以用http://172.17.0.1:11434(Docker 默认网关地址),在 Docker Desktop 环境用http://host.docker.internal:11434。我见过很多人在 Dify 配置页填localhost,结果一测试就报An error occurred during credentials validation。解决方式是在服务器上先验证:

curl http://172.17.0.1:11434/api/tags

如果返回{"models":[...]}说明 Dify 容器可以访问 Ollama,否则需要检查 Ollama 的监听地址。默认情况下 Ollama 只绑定 127.0.0.1,外部容器访问不到。这时要改环境变量:

# 修改 /etc/systemd/system/ollama.service 或通过 systemctl edit ollama [Service] Environment="OLLAMA_HOST=0.0.0.0:11434"

然后重启 Ollama。这个操作涉及内网安全,建议用防火墙限制 11434 端口的来源 IP,只放行 Dify 容器的网关 IP 和必要的运维网段。

4.2 DeepSeek-r1 在 Dify 中的模型接入:不止是填一个模型名

当你把 Ollama 供应商配好,在 Dify 里设置对话模型时,模型列表下拉菜单会从 Ollama 实例的/api/tags接口拉取已有模型。理论上你只需要选择deepseek-r1:7b即可。但幕僚云这类需要多模型配合的场景,我建议在供应商配置里把每个用途的模型分成不同条目管理,避免对话模型和推理模型混在一起难排查。

# 这是我在 Dify 中针对 Ollama 供应商的模型配置思路 # LLM 对话:deepseek-r1:7b(日常问答) # LLM 推理:deepseek-r1:14b(复杂分析任务) # Embedding:bge-m3(知识库向量化)

在 Dify 的工作流里,你可以分别为不同节点指定模型。比如“问题分类”节点用 7B 模型降低成本,“深度分析”节点用 14B 模型保证质量。Dify 的模型配置是按节点粒度生效的,不是全局只有一个模型。这一点用好之后,幕僚云的整体推理成本能被明显压下来——简单问题走小模型,复杂任务才走大模型。

还有一个细节是 DeepSeek-r1 的 API 格式。Dify 通过 OpenAI 兼容接口调用 Ollama,而 DeepSeek-r1 的推理输出会包含thinking和final answer两部分。Ollama 默认返回的响应里带有reasoning字段,Dify 在较新版本里能够把推理过程单独提取显示,但在设置提示词时要注意:如果系统提示词把推理段落和正式回答混在一起理解,最终答案的格式可能会乱。我的做法是在工作流的提示词里明确写“请给出最终结论,不需要输出思考过程”,然后让 Dify 只展示输出内容。

4.3 工作流编排:从模型能力到幕僚云业务应用的桥

模型接进来之后,真正的价值在于用 Dify 工作流把模型能力串成业务逻辑。幕僚云常见的应用类型包括:内部制度问答助手、合同要点提取器、项目周报生成器、数据查询对话代理。每种应用对应不同的工作流形态,但基础模式是一致的:先编排流程,再挂知识库,最后做权限隔离。

以“内部制度问答助手”为例,工作流至少包含四个节点:问题输入、知识库检索、模型生成、答案输出。在 Dify 里实现时,知识库检索节点要用 embedding 模型做召回,模型生成节点用 deepseek-r1:7b 做答案合成。这里的参数调整点是“召回数量”和“相似度阈值”。幕僚云里的制度文档往往有大量相近表述,我把检索的 TopK 设置在 5 到 8 条、相似度阈值设置在 0.3 左右,避免漏召回。

# Dify 工作流中“知识库检索”节点的关键参数 检索方式: 混合检索(全文 + 向量) 召回数量: 5-8 相似度阈值: 0.3 重新排序: 启用(如果配置了 rerank 模型)

工作流编排完成后,Dify 会自动生成一个 API 接口,通过 API Key 调用。这样幕僚云的前端应用不需要直连数据库或直接调模型,而是统一走 Dify 的 API 网关。API 层的额外好处是:你可以在 Dify 后台看到每次请求的完整链路追踪,包括每一步的耗时和 token 消耗。这一点在生产排障时价值极大。

5. 私有化部署避坑指南:这 5 个坑我几乎每次都会遇到

5.1 Ollama 端口绑定导致 Dify 凭证校验失败

现象:在 Dify 后台配置 Ollama 供应商后,点击“测试”一直报错,提示 credential validation failed。但你在服务器上直接 curl Ollama 的接口,响应是正常的。

原因:Ollama 默认只监听 127.0.0.1。Dify 的 api 容器运行在 Docker 网络里,它访问宿主机时走的是 docker0 网桥的网关 IP,无法到达 127.0.0.1 上的 Ollama 服务。

解决:修改 Ollama 的监听地址为0.0.0.0:11434,然后重启。具体操作是通过sudo systemctl edit ollama增加Environment="OLLAMA_HOST=0.0.0.0:11434",再systemctl daemon-reload && systemctl restart ollama。同时用防火墙只允许内网网段和 Docker 网段访问 11434 端口。验证命令是ss -tlnp | grep 11434,看到0.0.0.0:11434就代表修改生效。

5.2 Dify 容器内访问宿主机不能用 localhost

现象:Dify 后台能保存配置,但调用模型时超时或连接拒绝,日志里出现 “Connection refused”。

原因:Dify 的 api 容器内的 localhost 指向容器自己,而不是宿主机。API Base URL 写错是这个问题的最常见来源。

解决:Linux 环境写http://172.17.0.1:11434,这是 Docker 默认网关地址。Docker Desktop 环境写http://host.docker.internal:11434。如果你修改了 Docker 网络模式或自定义了网段,用docker network inspect bridge查看网关地址,以实际为准。另外注意 URL 尾部不需要加/v1,Dify 会自动拼接。

5.3 显存不够时模型加载被反复卸载:QPS 直线下降

现象:幕僚云上线后,第一个请求要等 20 到 30 秒才返回,但同一个模型之前测试时响应挺快。

原因:并发请求增多后,模型在显存和内存之间反复换入换出。DeepSeek-r1 14B 的 Q4 量化大约需要 10GB 显存,如果 GPU 只有 8GB,Ollama 会自动把部分层加载到内存。当请求一多,频繁换层导致性能急剧劣化。

解决:两个方向。一是控制并发,Dify 侧把单模型的并发数调低;二是换更大的显存卡,或者改用 7B 模型。如果你必须用 14B 且只有 8GB 卡,尝试OLLAMA_NUM_GPU=999强制全量入显存,然后观察是否 OOM。更务实的做法是准备两张卡,Ollama 是支持多卡并行加载的。还有一点:确认 GPU 是否真的在用,nvidia-smi看进程,如果 Ollama 没有出现在 GPU 进程里,说明它走了 CPU 推理,需要检查OLLAMA_DEBUG日志和无显卡时的降级行为。

5.4 向量化任务全部失败:Embedding 模型没配对

现象:上传文档到知识库后,文档状态一直停留在“待索引”,日志显示 embedding 调用失败。

原因:Dify 在索引文档时需要调用 embedding 模型完成向量化。如果你只配置了对话模型、没有配置 embedding 模型,或者 embedding 模型的名称填错,索引任务就会失败。

解决:回到模型供应商设置里,确认 Ollama 实例中已拉取 embedding 模型。用ollama list查看名称是否匹配。然后到 Dify 的“知识库”设置里,指定“Embedding 模型”为 bge-m3 这类可用模型。改完后再传一次文档,观察索引状态是否变成“已完成”。另外注意 embedding 模型的上下文长度,文档分段超过模型上限也会导致失败。

5.5 Dify 升级后模型配置丢失

现象:幕僚云做例行升级,Dify 从旧版本升到 1.10+,登录后发现所有模型供应商都要重新配,API Key 也失效了。

原因:Dify 的模型配置以加密形式存在数据库里,升级脚本有时会重置加密密钥或迁移用户数据不完整。另外如果你用了 .env 里自定义的SECRET_KEY,升级时没有沿用同一个值,已有的模型凭证就解不开。

解决:升级前备份数据库和 .env。.env里的SECRET_KEY、DB_PASSWORD、REDIS_PASSWORD务必保持与旧版本一致。如果已经升级完且凭证丢失,唯一的办法是在新版本里重新录入模型供应商信息,没有后悔药。我现在的做法是每次升级前记录当前所有模型供应商的名称和模型列表,然后单独导出。Dify 官方也提供了数据库备份命令,可以用docker compose exec api flask db backup之类的工具预处理。

6. 幕僚云跑通之后:验证清单、监控与一个小技巧

部署完成不等于交付完成。我会按下面的顺序做一套冒烟测试,全部通过才敢把地址交给业务方。

第一步,在服务器上验证 Ollama 状态:

# 确认 Ollama 服务健康 curl http://localhost:11434/api/tags # 直接调一次推理,确认模型没有加载问题 curl http://localhost:11434/api/generate -d '{ "model": "deepseek-r1:7b", "prompt": "你好,请用一句话介绍你自己", "stream": false }'

第二步,在 Dify 管理后台跑一次“模型供应商 → 测试”,确认对话和 embedding 均可用。第三步,创建一个最简单的“问答助手”应用,挂上测试知识库,跑通一个问题。第四步,用 Dify 生成的 API 地址做一次带 Key 的请求:

curl -X POST http://<dify-host>/v1/chat-messages \ -H "Authorization: Bearer <app-api-key>" \ -H "Content-Type: application/json" \ -d '{ "inputs": {}, "query": "幕僚云内部报销流程是什么", "response_mode": "blocking", "user": "test-user" }'

如果返回 200 且消息内容包含合理回答,这套链路就是通的。

日常运维上,我用两个习惯来保障稳定。一个是定期查看ollama ps,它能显示当前加载了哪些模型、显存占用和剩余上下文窗口。另一个是盯 Dify 的日志,容器日志里如果出现响应超时或上游连接重置,优先检查 Ollama 侧的并发压力和 GPU 利用率。

最后说一个小技巧:在同一台 GPU 服务器上跑了多个 Ollama 模型时,你会发现模型切换会有冷却时间。为了避免 Dify 里不同应用频繁切换模型导致体验卡顿,我习惯按应用分组分配模型。比如幕僚云的“制度问答”应用固定用 7B 模型,“数据分析”应用单独用 14B 模型,而不是让所有应用共享全部模型。这样配合 Ollama 的 keep_alive 参数,模型会保持常驻,响应速度会稳定很多。

# 让模型保持 30 分钟不卸载 curl http://localhost:11434/api/generate -d '{ "model": "deepseek-r1:7b", "prompt": "ping", "keep_alive": "30m", "stream": false }'

这也算是我从多次生产事故里总结出来的经验:私有化部署最难的不是把东西装起来,而是让它稳定地跑在被人依赖的位置上。每一次模型加载延迟、每一次凭证失效,看起来都是小事,但积累起来就会消耗团队对这套系统的信任。希望这篇笔记能帮你少走几步弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询