2602 字
13 分钟
用 Docker 部署 Ollama 与 Open WebUI 搭建本地大模型

用 Docker 部署 Ollama 与 Open WebUI 搭建本地大模型#

1 序言#

用别人的 API 有两个绕不开的问题:一是数据要出内网,你问的任何东西都会先经过人家服务器;二是按量计费,用得多了心慌。

而家里那台常年开机的 NAS,其实已经具备跑大模型的条件——只要它能跑 Docker。本文记录我在 Debian 12 / 飞牛 OS 上用 Docker 部署 Ollama(推理服务) + Open WebUI(网页对话界面) 的完整过程,重点解决三个问题:

  • 我这台机器到底能跑多大的模型(第二章先算硬件账,别装完才发现跑不动);
  • 怎么用 docker-compose 一次装好(第三、四章);
  • 怎么让速度可接受(第六章,默认参数下 GPU 利用率往往只有一半)。

全程只用到 Docker,不需要编译、不需要装 Python 环境。

2 先算硬件账#

这一步别跳过。很多人部署失败不是命令写错,是模型选大了。

2.1 三条硬指标#

跑大模型只看三样东西:显存、内存、磁盘。

  • 显存:决定模型能不能跑在 GPU 上。放不下就会自动降级到 CPU,速度掉一个数量级。
  • 内存:CPU 推理时模型权重全部加载到内存;GPU 推理时也需要内存存放 KV Cache 的溢出部分。
  • 磁盘:模型文件体积,通常是显存的 1.2 倍左右。

2.2 显存怎么估#

一个够用的经验公式:

显存需求 ≈ 参数量(亿) × 量化位数 ÷ 8 (GB) + KV Cache 余量

以 Q4 量化(4 bit)为例,各规格的参考值:

模型参数Q4 量化显存模型文件大小运行内存建议
1.5B约 1.5 GB约 1 GB4 GB
7B / 8B约 5 GB约 4.7 GB8 GB
14B约 9 GB约 9 GB16 GB
32B约 20 GB约 19 GB32 GB
70B约 40 GB约 40 GB64 GB

必须留余量。上表是「刚好装下」的数,实际还要给 KV Cache(上下文越长占用越大)和系统留 1–3 GB。所以 8 GB 显存跑 7B/8B 是舒服的,跑 14B 就会爆。

2.3 三种部署形态#

部署形态典型硬件7B 模型速度预期适合什么
纯 CPU无独显,普通 x862–5 tokens/s偶尔问答,能接受慢
核显 / 小主机Intel N100、ARM 盒子3–8 tokens/s轻量问答、翻译
独立显卡RTX 3060 12G 及以上30–80 tokens/s日常主力,体验接近在线服务

我自己的建议:核显和纯 CPU 只适合「能用就行」的场景。如果你打算天天用,一张 12G 显存的二手卡(如 3060 12G)性价比最高,7B、8B、14B 都能舒服跑。

3 部署 Ollama#

Ollama 负责加载模型、对外提供 API,是整套方案的引擎,默认监听 11434 端口。

3.1 前置:NVIDIA 显卡需装容器工具包#

只有用 NVIDIA 独显 才需要这一步,核显和纯 CPU 跳过。

Terminal window
# 添加 NVIDIA 容器工具包源
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update
sudo apt install -y nvidia-container-toolkit
sudo systemctl restart docker

装完先验证宿主机能识别显卡:

Terminal window
nvidia-smi

只要能看到显卡型号和显存占用表,就说明驱动正常。

3.2 docker-compose.yaml#

我沿用「yaml 文件与数据分开」的目录习惯,路径建在 /docker/apps/docker-compose/ 下:

Terminal window
mkdir -p /docker/apps/docker-compose/ollama
cd /docker/apps/docker-compose/ollama

新建 docker-compose.yaml:

# 官方文档
# https://hub.docker.com/r/ollama/ollama
# https://github.com/ollama/ollama
---
name: ollama
# 最后编辑时间:2026-09-23
services:
ollama:
# 镜像地址
image: ollama/ollama:latest
# 容器名
container_name: ollama
# 主机名
hostname: ollama
# 调用宿主机 GPU(无独显请整段删除)
gpus: all
volumes:
# 模型与配置持久化,重装容器不丢模型
- /docker/apps/ollama:/root/.ollama
environment:
# 时区
TZ: Asia/Shanghai
# 模型在显存中空闲驻留时长,-1 表示不卸载
OLLAMA_KEEP_ALIVE: "30m"
# 单模型最大并行请求数,显存小的机器保持 1
OLLAMA_NUM_PARALLEL: "2"
# 同时常驻显存的模型数量上限
OLLAMA_MAX_LOADED_MODELS: "1"
ports:
# API 端口,局域网内其他设备也靠它调用
- 11434:11434
# 重启策略,总是重启
restart: always

启动:

Terminal window
# 拉取镜像并后台启动
docker compose pull && docker compose up -d
# 查看日志,确认没有报错
docker compose logs -f ollama

⚠️ 没有独显的机器务必删掉 gpus: all 这一行,否则容器会启动失败并提示找不到 GPU。

3.3 验证#

Terminal window
# 看容器状态,STATUS 应为 Up
docker ps | grep ollama
# 拉一个小模型测试(首次会下载约 1GB)
docker exec -it ollama ollama pull qwen2.5:1.5b
# 命令行直接对话,输入 /bye 退出
docker exec -it ollama ollama run qwen2.5:1.5b

到这里 Ollama 已经能用了,只是个命令行。下面给它配个网页界面。

4 部署 Open WebUI#

Open WebUI 是一个自托管的对话前端,界面接近 ChatGPT,支持多模型切换、对话历史、文件上传,并且默认就能对接 Ollama。

4.1 docker-compose.yaml#

Terminal window
mkdir -p /docker/apps/docker-compose/open-webui
cd /docker/apps/docker-compose/open-webui

新建 docker-compose.yaml:

# 官方文档
# https://github.com/open-webui/open-webui
# https://docs.openwebui.com
---
name: open-webui
# 最后编辑时间:2026-09-23
services:
open-webui:
# 镜像地址,CPU 机器可选 :main,追求体积可换 :main-slim
image: ghcr.io/open-webui/open-webui:main
# 容器名
container_name: open-webui
# 主机名
hostname: open-webui
# 🔴 关键:使用 host 网络,容器与宿主机共享网络栈
# 好处是能直接通过 127.0.0.1 访问 Ollama,无需额外建网络
# 注意:host 模式下 ports 段会被忽略,WebUI 默认监听 8080,直接访问宿主 IP 即可
network_mode: host
environment:
# 时区
TZ: Asia/Shanghai
# 🔴 关键:告诉 Open WebUI 去哪找 Ollama
# host 网络下走本机地址;若两者在自定义 bridge 网络里,则填 http://ollama:11434
OLLAMA_BASE_URL: http://127.0.0.1:11434
# 关闭首次启动的联网检查,内网环境更快
OFFLINE_MODE: "true"
# 首次访问自动创建的账号(不设则第一个注册的人成为管理员)
# WEBUI_AUTH: "false"
volumes:
# 数据持久化(用户、对话、配置)
- /docker/apps/open-webui:/app/backend/data
# 重启策略,总是重启
restart: always

启动:

Terminal window
docker compose pull && docker compose up -d

4.2 首次登录#

浏览器打开 http://你的内网IP:8080。

  • 第一个注册的账号自动成为管理员,注册后建议在「设置 → 管理员设置」里关掉公开注册。
  • 进入后左上角能看到模型列表。如果列表是空的,说明没连上 Ollama,回到 7.1 排查。
  • 中文界面:右上角头像 → Settings → General → Language,选「简体中文」。

5 模型选择与拉取#

5.1 中文场景的实用组合#

用途推荐模型拉取大小建议显存
日常问答、写作qwen2.5:7b约 4.7 GB8 GB
强推理、数学deepseek-r1:8b约 5 GB8 GB
轻量问答、翻译qwen2.5:3b约 2 GB4 GB
文字向量(RAG 用)bge-m3约 1.2 GB4 GB

中文场景优先选 Qwen 系。同一参数量下,Qwen 的中文表达和指令遵循明显优于 Llama,这是实测结论不是偏好。

5.2 常用命令#

Terminal window
# 拉取模型
docker exec -it ollama ollama pull qwen2.5:7b
# 列出本地已有模型
docker exec -it ollama ollama list
# 删除模型(释放磁盘)
docker exec -it ollama ollama rm qwen2.5:1.5b
# 查看某个模型占了多少显存
docker exec -it ollama ollama ps

拉取完成后回到 Open WebUI 刷新页面,模型就会出现在左上角下拉框里。

6 性能调优#

默认参数下 GPU 利用率往往只有一半,调整下面三项能明显提速。

6.1 让模型常驻显存#

OLLAMA_KEEP_ALIVE 控制模型空闲多久后从显存卸载。默认 5 分钟,意味着你每聊几句就要重新加载一次(7B 模型加载约 5–10 秒)。改成 30m 或 -1:

environment:
OLLAMA_KEEP_ALIVE: "-1" # 永不卸载,显存充足时最快

代价:模型会一直占着显存。如果机器还要跑别的吃显存的活(比如相册缩图、转码),建议设 30m 折中。

6.2 上下文长度#

上下文越长,KV Cache 占用越大。Open WebUI 里可以在「设置 → 高级参数」调 num_ctx:

num_ctx7B 模型额外显存适合
2048约 0.5 GB短问答,最省
4096约 1 GB默认,日常够用
8192约 2 GB长文档、代码
32768约 8 GB长文总结,8G 显存跑不动

6.3 实测参考#

在我的环境(RTX 3060 12G,7B Q4)实测:

配置首字延迟生成速度
默认(keep_alive 5m,num_ctx 2048)8–10 s(含加载)约 45 tokens/s
keep_alive -1,num_ctx 2048< 1 s约 48 tokens/s
keep_alive -1,num_ctx 8192< 1 s约 38 tokens/s

结论:首字延迟的差距几乎全部来自模型加载。常驻显存是收益最大的一项调整。

7 常见问题#

7.1 容器里看不到 GPU#

现象:日志出现 no CUDA-capable device 或 nvidia-smi 报错。

排查顺序:

  • 宿主机 nvidia-smi 是否正常(不正常是驱动问题,与 Docker 无关);
  • 是否装了 nvidia-container-toolkit 并重启过 Docker;
  • compose 里是否写了 gpus: all;
  • 飞牛 OS 等定制系统可能需要在应用中心额外启用 GPU 支持。

7.2 爆显存 / 速度突然掉到个位数#

现象:日志出现 CUDA out of memory 或速度骤降。

原因通常是模型没完全放进显存,Ollama 自动把部分层分给了 CPU。用 ollama ps 查看,正常应显示 100% GPU:

Terminal window
docker exec -it ollama ollama ps

如果显示 xx%/xx% CPU/GPU,说明显存不够:换更小的量化版本(如 qwen2.5:7b-instruct-q4_K_M)、降低 num_ctx,或者减少 OLLAMA_MAX_LOADED_MODELS。

7.3 输出被截断 / 答到一半停了#

一般是上下文窗口被占满。调大 num_ctx,或者开一个新对话(历史越长占用越多)。Open WebUI 可以在「设置 → 通用 → 请求」里限制携带的历史消息条数。

7.4 局域网其他设备访问不了#

11434(Ollama)和 8080(Open WebUI)都要在宿主机放行。在 Open WebUI 的「管理员设置 → 连接」里把 Ollama 地址改成宿主机内网 IP(如 http://192.168.x.x:11434),这样手机、平板都能用同一个入口。

想让它在外网也能访问?不要直接把端口转发出去。用 Lucky 反代加一层认证,具体做法见同目录的另一篇《用 New API 搭建统一 LLM 网关与 Lucky 反代外网访问》。

8 总结#

  • 先算显存再选模型,8 GB 显存是「舒服跑 7B/8B」的门槛,别无脑上 14B。
  • Ollama 管推理、Open WebUI 管界面,两个容器各司其职,加起来不到 10 行 compose。
  • 收益最大的调优是 OLLAMA_KEEP_ALIVE,它直接决定你每次提问要不要等 10 秒。
  • 本地部署的价值在隐私和离线,不在省钱。追求能力上限还是得用在线模型,两者不冲突——用网关把它们统一起来即可。

Created with ❤️ by 张萌萌

用 Docker 部署 Ollama 与 Open WebUI 搭建本地大模型
https://zmm.nw177.cn/posts/10-技术专栏/50-ai/01用-docker-部署-ollama-与-open-webui-搭建本地大模型/
作者
张萌萌
发布于
2026-09-23
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

评论

正在加载评论...