ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

DeepTutor Docker化部署实战:Ollama与Embedding模型容器编排指南

DeepTutor Docker化部署实战:Ollama与Embedding模型容器编排指南 1. 为什么我要把 DeepTutor 塞进 Docker 里先说结论DeepTutor 这套东西如果你打算长期用、反复用、换机器用那 Docker 化几乎是唯一正确的选择。我最早是在一台 Ubuntu 测试机上裸装 DeepTutor 的Python 版本冲突、CUDA 驱动版本对不上、Embedding 模型下载路径写死、Ollama 服务端口被占……折腾了整整一个下午才跑通。后来换了一台机器同样的流程又踩了一遍坑。那一刻我就决定必须把它容器化。DeepTutor 本质上是一个基于大语言模型的智能辅导/知识问答系统它的核心链路是用户提问 → 向量检索Embedding→ 上下文拼接 → 大模型生成回答。这条链路里涉及三个关键组件DeepTutor 应用本体、Ollama 推理服务、Embedding 模型服务。任何一个组件的版本或配置出问题整条链路就断了。Docker 的价值就在于把这套依赖关系固化下来做到一次构建到处运行。这篇文章适合三类人看第一类是想快速体验 DeepTutor 但不想折腾环境的新手第二类是想把 DeepTutor 部署到内网服务器、做私有化知识库的运维同学第三类是想基于 DeepTutor 做二次开发、需要一套干净可复现环境的开发者。我会从架构设计讲到实操步骤再到踩坑排查尽量把每个决策背后的为什么讲清楚。需要提前说明的是本文涉及的模型推理全部基于本地部署方案所有数据和服务都在你自己的机器上闭环不涉及任何外部网络依赖。这也是我选择 Ollama 本地 Embedding 的核心原因——可控、可复现、可离线。2. 整体架构设计与组件选型思路2.1 三个核心组件的职责划分在动手之前先把架构想清楚不然后面容器编排会一团乱。我把 DeepTutor 的部署拆成三个独立的服务单元组件职责技术选型端口DeepTutor AppWeb 界面 业务逻辑 检索编排Python FastAPI / 官方镜像8000Ollama大模型推理生成回答Ollama Server11434Embedding 服务文本向量化检索用Ollama 内置 embedding 或独立服务11434 / 自定义这里有个关键决策点Embedding 到底用 Ollama 内置的还是单独起一个服务我的建议是如果你只是个人使用、知识库规模在几万条以内直接用 Ollama 拉一个 embedding 模型比如nomic-embed-text或bge-m3就够了省一个容器。但如果你要做生产级部署、检索量很大、需要独立扩缩容那就把 Embedding 单独拆出来用专门的推理框架跑避免和生成模型抢显存。2.2 为什么选 Ollama 而不是其他推理框架市面上本地推理方案不少我最终选 Ollama 的理由很实际模型管理简单ollama pull一条命令搞定不用手动下载 GGUF 文件、不用配 tokenizer 路径。API 兼容 OpenAI 格式DeepTutor 如果用的是 OpenAI SDK 调用方式改个 base_url 就能对接几乎零改造。跨平台Windows、Linux、macOS 都有对应版本团队里不同系统的同学都能用。显存调度省心Ollama 会自动管理模型加载和卸载不用自己写显存回收逻辑。当然它也有缺点比如并发能力弱、不支持复杂的批处理调度。但对于 DeepTutor 这种以交互式问答为主的场景够用了。2.3 网络拓扑与容器通信设计容器之间怎么通信这是新手最容易翻车的地方。我见过太多人把 Ollama 装在宿主机、DeepTutor 装在容器里然后容器里用localhost:11434去连结果一直 connection refused。正确的做法是把所有服务放进同一个 Docker 网络容器之间用服务名互相访问。比如 DeepTutor 容器里配置 Ollama 地址时写http://ollama:11434而不是http://localhost:11434。Docker 的内置 DNS 会把ollama这个服务名解析到对应容器的 IP。如果你坚持 Ollama 跑在宿主机比如为了直接用宿主机的 GPU 驱动那容器里要用http://host.docker.internal:11434Docker Desktop 环境或者宿主机的实际局域网 IP。这个细节后面实操部分我会再展开。3. 环境准备与 Docker 安装实操3.1 Ubuntu 下的 Docker 安装先解决 Docker 本身。Ubuntu 上我习惯用官方脚本装比 apt 源里的版本新也省得配一堆依赖# 卸载旧版本如果有 sudo apt-get remove docker docker-engine docker.io containerd runc # 安装依赖 sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release # 添加官方 GPG key sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 添加源 echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装 sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin装完之后有个必做动作把当前用户加进 docker 组否则每次敲 docker 命令都要 sudo烦得很sudo usermod -aG docker $USER newgrp docker注意newgrp只对当前终端生效其他已经打开的终端需要重新登录。如果执行 docker 命令还是报permission denied while trying to connect to the docker api八成就是这个组权限没生效退出 SSH 重连一次即可。3.2 Windows 下的 Docker Desktop 安装Windows 用户直接去官网下 Docker Desktop 安装包双击一路下一步。但有三个坑必须提前说第一WSL2 后端必须开启。Docker Desktop 默认用 WSL2如果你机器上没装 WSL2安装程序会提示你装。装完记得在 BIOS 里确认虚拟化VT-x / AMD-V是打开的否则 WSL2 起不来。第二磁盘空间。Docker 的镜像和容器默认存在 C 盘Ollama 的模型动辄几个 G很容易把 C 盘撑爆。我建议在 Docker Desktop 设置里把 Disk image location 改到 D 盘或更大的盘。第三端口占用。Windows 上 11434 端口有时候会被其他服务占用装之前先netstat -ano | findstr 11434查一下。3.3 GPU 支持配置NVIDIA 显卡如果你有 NVIDIA 显卡想让 Ollama 用上 GPU 加速需要额外装 NVIDIA Container Toolkit# 添加源 distribution$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list # 安装 sudo apt-get update sudo apt-get install -y nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtimedocker sudo systemctl restart docker验证是否成功docker run --rm --gpus all nvidia/cuda:12.0-base nvidia-smi能打印出显卡信息就说明 OK。这一步不做的话Ollama 会退化成纯 CPU 推理速度慢到你怀疑人生。4. Ollama 服务部署与模型拉取4.1 用 Docker 跑 OllamaOllama 官方提供了 Docker 镜像直接跑就行docker run -d \ --name ollama \ --gpus all \ -p 11434:11434 \ -v ollama_data:/root/.ollama \ --restart unless-stopped \ ollama/ollama:latest几个参数解释一下--gpus all是让容器能用所有 GPU-v ollama_data:/root/.ollama是把模型文件挂到命名卷上这样容器删了模型还在--restart unless-stopped保证开机自启。实操心得模型存储路径一定要挂出来。我见过有人没挂卷容器一重建几十 G 的模型全没了又得重新下载。如果你想把模型存到特定盘比如数据盘把ollama_data换成/data/ollama:/root/.ollama这种绝对路径挂载。4.2 拉取 DeepSeek 与 Embedding 模型Ollama 跑起来后进容器拉模型# 拉取 DeepSeek 系列模型按你的显存选尺寸 docker exec -it ollama ollama pull deepseek-r1:7b # 拉取 Embedding 模型 docker exec -it ollama ollama pull nomic-embed-text模型尺寸怎么选给你一个粗略的参考表模型参数量显存需求约适用场景deepseek-r1:1.5b1.5B2-3 GB低配机器、快速验证deepseek-r1:7b7B6-8 GB个人使用、平衡之选deepseek-r1:14b14B12-16 GB效果更好、需要中端显卡deepseek-r1:32b32B24 GB专业级、高端显卡Embedding 模型我推荐nomic-embed-text768 维体积小、速度快中文效果也还行。如果你对中文检索要求高可以换bge-m31024 维效果更好但更吃资源。注意ollama pull下载慢是常态尤其是国内网络环境。如果实在拉不动可以找离线模型包手动放到/root/.ollama/models目录下。离线包的目录结构要和 Ollama 的存储格式一致否则识别不了。4.3 验证 Ollama 服务拉完模型验证一下服务是否正常# 列出已安装模型 curl http://localhost:11434/api/tags # 测试生成 curl http://localhost:11434/api/generate -d { model: deepseek-r1:7b, prompt: 你好请介绍一下你自己, stream: false }能返回 JSON 结果就说明 Ollama 工作正常。如果报错先看容器日志docker logs ollama。5. DeepTutor 容器化部署全流程5.1 用 docker-compose 编排所有服务单个docker run命令管理多个服务太累我强烈建议用 docker-compose。新建一个docker-compose.ymlversion: 3.8 services: ollama: image: ollama/ollama:latest container_name: ollama ports: - 11434:11434 volumes: - ollama_data:/root/.ollama deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] restart: unless-stopped deeptutor: image: deeptutor/deeptutor:latest container_name: deeptutor ports: - 8000:8000 environment: - OLLAMA_BASE_URLhttp://ollama:11434 - LLM_MODELdeepseek-r1:7b - EMBEDDING_MODELnomic-embed-text - VECTOR_DB_PATH/app/data/vectors volumes: - deeptutor_data:/app/data depends_on: - ollama restart: unless-stopped volumes: ollama_data: deeptutor_data:这里的关键是OLLAMA_BASE_URLhttp://ollama:11434用服务名而不是 localhost。depends_on保证 Ollama 先启动。5.2 启动与初始化# 启动所有服务 docker compose up -d # 查看状态 docker compose ps # 看日志 docker compose logs -f deeptutor第一次启动 DeepTutor 时它可能需要初始化向量数据库、下载一些依赖。耐心等几分钟看到日志里出现 Application startup complete 之类的字样就说明好了。5.3 访问与基础配置浏览器打开http://你的服务器IP:8000应该能看到 DeepTutor 的界面。第一次进去要做几件事配置模型在设置里确认 LLM 模型名和 Embedding 模型名要和 Ollama 里拉的一致。上传知识库把你的文档PDF、Markdown、TXT传进去系统会自动切分、向量化、入库。测试问答问一个知识库里有的问题看能不能正确检索并回答。实操心得知识库文档切分粒度很影响检索效果。切太碎上下文不完整切太大检索精度下降。我一般把 chunk size 设在 500-800 字符overlap 设 100-150 字符。这个参数在 DeepTutor 的配置里能调具体看版本。6. 常见问题排查与避坑指南6.1 容器连不上 Ollama这是最高频的问题。排查顺序现象可能原因解决方法connection refused用了 localhost改成服务名http://ollama:11434timeout不在同一网络确认在同一 compose 文件里404模型名写错ollama list核对模型名显存不足模型太大换小模型或加显卡6.2 模型下载慢或失败ollama pull卡住不动先 CtrlC 中断然后# 检查网络 docker exec -it ollama curl -I https://registry.ollama.ai # 重试加长超时 docker exec -it ollama ollama pull deepseek-r1:7b如果反复失败考虑离线方案在能下载的机器上拉好模型把/root/.ollama/models整个目录打包拷过来。6.3 GPU 没被用上跑推理时nvidia-smi看不到进程说明 Ollama 在用 CPU。检查# 容器内能否看到 GPU docker exec -it ollama nvidia-smi如果容器内看不到说明启动时没加--gpus all或者 NVIDIA Container Toolkit 没配好。回到 3.3 节重新配。6.4 向量检索结果不准如果问答答非所问大概率是 Embedding 或切分的问题。排查思路换更强的 Embedding 模型bge-m3比nomic-embed-text中文效果好调整 chunk size 和 overlap检查文档是否真的入库了看向量库文件大小确认查询语言和文档语言一致中英文混用会影响效果6.5 容器重启后数据丢失这是没挂卷的典型症状。检查 compose 文件里每个服务的volumes配置确保模型、向量库、配置都挂出来了。已经丢了的只能重新拉、重新入库。7. 性能调优与扩展思路7.1 显存与并发调优Ollama 默认一次只处理一个请求并发上来会排队。如果你的场景并发高可以设置OLLAMA_NUM_PARALLEL环境变量提高并发数吃显存用多个 Ollama 实例 负载均衡把 Embedding 拆到独立服务避免和生成模型抢资源7.2 向量库选型DeepTutor 默认可能用轻量级向量库如 Chroma、FAISS。数据量大了之后可以考虑换成 Milvus 或 Qdrant支持分布式、更高性能。切换时注意 Embedding 维度要对齐否则检索全乱。7.3 反向代理与 HTTPS生产环境别直接暴露 8000 端口前面挂个 Nginx 做反向代理配上 HTTPS。这样既安全又能做访问控制。server { listen 443 ssl; server_name your-domain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }7.4 备份策略要备份的东西就三样Ollama 模型目录、DeepTutor 数据目录、compose 文件。写个定时脚本打包到异地出问题能快速恢复。#!/bin/bash DATE$(date %Y%m%d) docker run --rm -v ollama_data:/data -v /backup:/backup alpine \ tar czf /backup/ollama_$DATE.tar.gz -C /data .这套 Docker 化方案我在三台不同配置的机器上都跑过从 8G 显存的消费级显卡到 24G 的工作站流程完全一致唯一要改的就是模型尺寸。真正做到了换个机器改个模型名五分钟重新跑起来。如果你也在折腾 DeepTutor 的部署希望这些踩坑记录能帮你少走点弯路。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进