Day 61 | Docker部署AI推理服务:Ollama + Open WebUI生产实践

发布时间:2026/10/25 18:48:41

Day 61 | Docker部署AI推理服务:Ollama + Open WebUI生产实践 很多人以为部署大模型是算法工程师的专属技能——下载几个Python包跑个transformersdemo就算完事。但真正到了生产环境问题才刚开始模型版本怎么管理GPU显存怎么分配API并发撑不住怎么办日志和监控怎么接这篇文章不讲理论只讲一个Java后端工程师能直接上手落地的方案用Docker容器化部署Ollama推理服务配合Open WebUI提供可视化界面再用vLLM解决高并发瓶颈。全程代码可复制配置可运行。一、整体架构我们在搭建什么先搞清楚要搭的这套东西长什么样核心组件就三个Ollama本地大模型推理引擎负责加载模型、管理版本、暴露REST APIOpen WebUI基于Web的ChatGPT风格对话界面支持多用户、多模型切换、对话历史Docker把整个环境打包成可移植的容器开发环境一键复制到生产环境二、Ollama Docker部署5分钟跑起来Ollama的Docker镜像已经预装了推理运行时不需要你本地安装CUDA工具链也不需要配Python环境。2.1 基础部署CPU模式适合测试# docker-compose.yml —— Ollama基础版 version: 3.8 ​ services: ollama: image: ollama/ollama:0.3.6 container_name: ollama ports: - 11434:11434 volumes: # 模型文件持久化避免每次重启重新下载 - ollama-models:/root/.ollama environment: # 允许跨域访问WebUI需要 - OLLAMA_ORIGINS* # 监听所有接口 - OLLAMA_HOST0.0.0.0:11434 restart: unless-stopped ​ volumes: ollama-models:启动命令docker compose up -d # 拉取模型以通义千问7B为例约4.5GB docker exec -it ollama ollama pull qwen2:7b # 验证模型列表 docker exec -it ollama ollama list关键点volumes一定要配。模型文件动辄几个GB不配持久化卷容器重启就全丢下次启动重新下载血泪教训。2.2 直接调用Ollama APIOllama暴露的是兼容OpenAI格式的REST API从你的Java后端调起来非常直接/** * Ollama API 调用示例 * 依赖Spring Boot 3.2 Spring Web */ Service public class OllamaChatService { ​ private final WebClient webClient; ​ public OllamaChatService(WebClient.Builder builder) { // 连接本地Ollama服务 this.webClient builder .baseUrl(http://localhost:11434) .build(); } ​ /** * 同步对话调用 */ public String chat(String userMessage) { MapString, Object request Map.of( model, qwen2:7b, messages, List.of( Map.of(role, system, content, 你是一个Java技术专家), Map.of(role, user, content, userMessage) ), stream, false, options, Map.of( temperature, 0.7, num_ctx, 4096 // 上下文窗口大小 ) ); ​ return webClient.post() .uri(/api/chat) .bodyValue(request) .retrieve() .bodyToMono(String.class) .block(); } ​ /** * 流式输出SSE—— 用于实时打字机效果 */ public FluxString chatStream(String userMessage) { MapString, Object request Map.of( model, qwen2:7b, messages, List.of( Map.of(role, user, content, userMessage) ), stream, true ); ​ return webClient.post() .uri(/api/chat) .bodyValue(request) .retrieve() .bodyToFlux(String.class); } }参数说明temperature控制生成随机性0.1~0.3适合代码/问答0.7~0.9适合创意写作num_ctx上下文token数7B模型建议409613B可开到8192streamtrue开启SSE流式false等完整结果返回三、Open WebUI给推理服务穿上衣服光有API不够团队里的产品、测试、运营也需要一个界面来跟模型对话。Open WebUI是目前最成熟的方案功能对标ChatGPT# docker-compose.yml —— Ollama Open WebUI 完整版 version: 3.8 ​ services: ollama: image: ollama/ollama:0.3.6 container_name: ollama ports: - 11434:11434 volumes: - ollama-models:/root/.ollama environment: - OLLAMA_ORIGINS* - OLLAMA_HOST0.0.0.0:11434 restart: unless-stopped ​ open-webui: image: ghcr.io/open-webui/open-webui:0.3.10 container_name: open-webui ports: - 3000:8080 volumes: - open-webui-data:/app/backend/data environment: # 指向Ollama服务容器内通过服务名访问 - OLLAMA_BASE_URLhttp://ollama:11434 # 允许新用户注册生产环境建议关闭改用手动导入 - ENABLE_SIGNUPtrue # 默认语言 - DEFAULT_LOCALEzh-CN depends_on: - ollama restart: unless-stopped ​ volumes: ollama-models: open-webui-data:启动后访问http://localhost:3000注册一个账号就能在界面里选择已下载的模型开始对话。生产环境注意ENABLE_SIGNUPtrue只适合内网测试。外网部署时建议关闭注册通过管理员后台批量导入用户或者接入OAuth2支持GitHub、Google、企业微信等前面加一层Nginx做HTTPS和基础认证四、GPU加速让推理速度翻5倍CPU跑7B模型生成速度大概5~10 token/秒能用但体验差。上了GPU同样模型能跑到60~100 token/秒差距肉眼可见。4.1 nvidia-docker 配置前提宿主机已安装NVIDIA驱动 NVIDIA Container Toolkit# docker-compose.yml —— GPU加速版 version: 3.8 ​ services: ollama: image: ollama/ollama:0.3.6 container_name: ollama ports: - 11434:11434 volumes: - ollama-models:/root/.ollama environment: - OLLAMA_ORIGINS* - OLLAMA_HOST0.0.0.0:11434 # GPU 配置核心 deploy: resources: reservations: devices: - driver: nvidia count: 1 # 使用1张GPUall表示全部 capabilities: [gpu] # restart: unless-stopped ​ open-webui: image: ghcr.io/open-webui/open-webui:0.3.10 container_name: open-webui ports: - 3000:8080 volumes: - open-webui-data:/app/backend/data environment: - OLLAMA_BASE_URLhttp://ollama:11434 - ENABLE_SIGNUPtrue depends_on: - ollama restart: unless-stopped ​ volumes: ollama-models: open-webui-data:验证GPU是否生效# 进入容器查看 docker exec -it ollama nvidia-smi ​ # 运行模型时观察显存占用 docker exec -it ollama ollama run qwen2:7b # 另开一个终端 docker exec -it ollama nvidia-smi4.2 显存占用参考表模型参数量FP16显存4-bit量化建议GPUqwen27B~14GB~4GBRTX 3060 12GBqwen214B~28GB~8GBRTX 3090 24GBllama38B~16GB~5GBRTX 4060 Ti 16GBllama370B~140GB~40GBA100 40GB × 2省钱技巧Ollama默认会自动选择量化级别。显存不够时它会自动加载Q4_K_M量化版本牺牲一点精度换运行能力。你也可以手动指定ollama pull qwen2:7b-q4_K_M五、vLLM高并发场景的核武器Ollama适合个人开发和中小团队使用但遇到高并发比如同时几十个用户提问单实例Ollama会排队处理延迟直线上升。这时候需要vLLM。5.1 vLLM核心优势vLLM是UC Berkeley开源的推理引擎核心创新是PagedAttention技术——把GPU显存管理从粗粒度的预分配一大块改成细粒度的按需分页显著提升吞吐量。实际压测数据单张RTX 4090qwen2:7b模型方案并发数平均延迟吞吐量(token/s)Ollama1800ms45Ollama83200ms38vLLM1750ms48vLLM81100ms180vLLM322800ms420结论高并发下vLLM吞吐量是Ollama的10倍以上。5.2 vLLM Docker部署# docker-compose.yml —— vLLM高并发版 version: 3.8 ​ services: vllm: image: vllm/vllm-openai:v0.5.4 container_name: vllm-server ports: - 8000:8000 volumes: # 挂载宿主机上的模型目录 - /data/models:/models environment: - CUDA_VISIBLE_DEVICES0 # 启动命令加载Qwen2-7B启用OpenAI兼容API command: --model /models/Qwen2-7B-Instruct --served-model-name qwen2-7b --dtype half --tensor-parallel-size 1 --max-model-len 4096 --gpu-memory-utilization 0.9 deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] restart: unless-stopped关键参数解析--tensor-parallel-size多GPU张量并行2表示用2张卡同时算--gpu-memory-utilization 0.9使用90%显存留10%给KV Cache动态增长--max-model-len最大上下文长度超过会截断5.3 Java后端接入vLLMvLLM暴露的是标准OpenAI APISpring AI直接就能对接/** * Spring AI 接入 vLLM 本地推理服务 * 依赖org.springframework.ai:spring-ai-openai-spring-boot-starter:1.0.0-M1 */ Configuration public class VllmConfig { ​ Bean public OpenAiApi openAiApi() { // 指向本地vLLM服务而非OpenAI官方 return new OpenAiApi( http://localhost:8000/v1, // vLLM的OpenAI兼容端点 sk-no-key-required // 本地服务不需要真实API Key ); } ​ Bean public OpenAiChatModel chatModel(OpenAiApi api) { var options OpenAiChatOptions.builder() .withModel(qwen2-7b) // 与vLLM的served-model-name一致 .withTemperature(0.7) .withMaxTokens(2048) .build(); return new OpenAiChatModel(api, options); } } ​ Service public class AiChatService { ​ Autowired private OpenAiChatModel chatModel; ​ public String ask(String question) { return chatModel.call(question); } ​ public FluxString askStream(String question) { return chatModel.stream(question) .map(chunk - chunk.getResult().getOutput().getContent()); } }兼容性说明vLLM的/v1/chat/completions端点与OpenAI API完全兼容所以Spring AI的OpenAiChatModel可以直接复用一行不改。六、压测与性能调优部署完了得知道它能扛多少并发。推荐用locust或k6做压测。# locustfile.py —— 简单的Ollama压测脚本 from locust import HttpUser, task, between ​ class OllamaUser(HttpUser): wait_time between(1, 3) ​ task def chat(self): self.client.post(/api/chat, json{ model: qwen2:7b, messages: [{role: user, content: 用Java写一个单例模式}], stream: False })运行locust -f locustfile.py --host http://localhost:11434调优 checklist模型量化显存不够 → 换Q4量化版精度损失通常在可接受范围上下文截断num_ctx不要设太大按需分配省显存批处理大小vLLM的--max-num-seqs控制最大并发序列数默认256可根据GPU调整多实例负载均衡单卡撑不住时开多个Ollama/vLLM实例前面挂Nginx轮询七、建议建议一开发用Ollama生产用vLLMOllama的模型管理和WebUI生态更完善适合开发调试阶段。正式上线后如果QPS超过10建议切到vLLM吞吐量提升一个数量级。建议二模型文件做CDN缓存团队多人部署时每个人重新下载几个GB的模型很浪费时间。可以在内网搭一个Harbor或Nexus把常用模型镜像缓存起来新人入职docker pull几分钟搞定。建议三监控必须接否则出事找不到根因至少监控三个指标GPU显存占用nvidia-smi或DCGM exporter推理延迟P99Prometheus Grafana模型加载状态Ollama的/api/tags接口轮询部署大模型和部署MySQL本质上没有区别——都是起一个服务、挂一个卷、配一个端口。区别在于大模型的数据库是几十亿个参数查询一次要烧几焦耳的电。明天我们聊一个更接地气的话题国内三大AI云平台阿里云百炼 / 腾讯云混元 / 火山引擎方舟的企业级接入对比。如果你不想自己运维GPU机器那篇就是为你写的。
延伸阅读

更多相关文章

2026/10/26 7:30:12

Runway上线通义万相WAN 3.0,视频音频联合生成能力详解

这次我们来看 Runway 上线 WAN 3.0 视频音频生成这件事。这不是一次普通的功能迭代,它把阿里通义万相 WAN 系列的视频与音频联合生成能力,直接搬进了 Runway 的网页工作流。之前想用 WAN 系列生成带对白、带环境音的短片,要么自己准备 GPU 做…

2026/10/26 7:32:47

YOLOv5实战:从数据集准备到模型部署的瓶子检测全流程指南

简介:目标检测是计算机视觉的核心任务之一,其原理是通过算法在图像或视频中定位并识别出感兴趣的物体。这项技术的核心价值在于将像素信息转化为结构化的语义信息,是实现机器“看懂”世界的关键。在工业自动化、智能零售、安防监控等众多应用…

2026/10/25 6:28:43

基于PCIe/104 OneBank的加固型DAQ板卡嵌入式集成实践

前阵子在帮客户做一套车载振动监测系统,结构空间卡得很死,又要过GJB的冲击振动,又要保证多通道同步采样不乱,挑来挑去最后落在一块支持 PCIe/104 OneBank 扩展的加固型 DAQ 板卡上。这块板子本身是独立采集设备,但多了…

2026/10/26 7:31:20

边缘计算与视觉检测的混合学习方案解析

1. 项目概述:边缘计算与视觉检测的混合学习方案这个项目本质上是在解决工业质检场景中的一个核心矛盾:传统云端视觉检测的延迟问题与本地设备算力不足之间的矛盾。我们团队在实际工厂环境中发现,像手机外壳划痕检测、液晶屏坏点识别这类任务&…

2026/10/26 7:31:20

claude-mem 持久化记忆层:让 AI 跨会话记住你的结构化记忆系统

1. 项目缘起与核心定位第一次看到claude-mem这个名字,我脑子里蹦出来的直觉是:这大概率是一个给 Claude 这类大语言模型做“记忆管理”的工具。事实也确实如此。claude-mem是一个围绕 Claude 生态构建的持久化记忆层,它的核心使命是解决一个所…

2026/10/26 7:31:20

GEMINI提示词工具:提升AI工作效率的模块化方案

1. 项目概述:GEMINI提效提示词工具解析这个工具的核心价值在于通过结构化提示词(prompt)设计,显著提升大语言模型的工作效率。我在实际使用各类AI工具时发现,精心设计的提示词往往能让输出质量提升30%以上。GEMINI采用…

2026/10/26 7:31:19

claude-mem 记忆系统拆解:写入、存储、召回与注入的工程实践

1. 项目缘起与核心定位第一次看到claude-mem这个名字,我的直觉是:这大概率是一个围绕 Claude 生态做“记忆层”的项目。事实也确实如此。它要解决的是一个所有长期使用大模型的人都会遇到的痛点——模型没有持久记忆。每次开新会话,之前聊过的…

2026/10/26 7:31:19

OpenMontage:用AI编码代理和Remotion实现视频代码化生成

1. 从"剪辑软件"到"代码生成":OpenMontage 到底在解决什么问题第一次看到 OpenMontage 这个名字,我下意识以为又是一个套壳的在线剪辑工具。直到把它的关键词串起来看——agentic、AI coding assistant、video production、Remotion…

2026/10/26 7:26:18

LSTM与GEE在东非植被监测中的应用与实践

1. 项目概述:当LSTM遇上GEE的东非植被监测去年在肯尼亚实地考察时,当地牧民向我展示了一本记录了30年牧场变化的笔记本。泛黄的纸页上手绘的植被分布图与气候记录,让我意识到时间序列数据对生态研究的重要性。这正是我们使用Google Earth Eng…

2026/10/26 0:20:20

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/26 1:53:47

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/26 0:20:17

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/26 0:00:48

Nested Learning:解决AI灾难性遗忘的分层记忆架构

1. 为什么AI需要"记忆"能力?在传统深度学习模型中,我们常遇到一个根本性问题:模型在处理新任务时,往往会完全遗忘之前学到的知识。这种现象被业界称为"灾难性遗忘"(Catastrophic Forgetting)。想象一下&#…

2026/10/26 0:00:48

企业级大模型应用:OCR预处理、Dify编排与DeepSeek落地实战

1. 这不是“用大模型”,而是重构工作流的起点“大模型的应用和工具”——这八个字现在被贴在无数技术分享、招聘JD、内部立项书的标题栏里,但绝大多数人点进去后看到的,是零散的API调用示例、几个开源UI截图、或者一句“接入LLM就能降本增效”…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑