适用场景
手里已经有能跑的大模型(本地 Ollama、vLLM、LM Studio,或者云端 OpenAI 兼容接口),但命令行聊天不方便,团队里其他人也不会用终端。这套方案用 Docker 起一个 Open WebUI,得到一个类 ChatGPT 的网页界面:支持多轮对话、历史记录、文件上传、多用户账号与权限、模型切换,数据全部落在自己服务器上。
适合:小团队内部自建 AI 助手入口、个人开发者想统一管理多个模型 API、企业希望对话记录不出内网。
环境与前置条件
- 操作系统:Linux(Ubuntu / Debian / CentOS 系均可)、macOS、Windows + WSL2。生产环境建议 Linux。
- Docker:Docker Engine 20.10 以上 + Docker Compose V2(命令是
docker compose,不是老的docker-compose)。具体版本以 Docker 官方文档当前版本为准。 - 内存:只跑 Open WebUI 本身,1 GB 内存可以起步,2 GB 更稳妥(要跑向量化、处理文档时会吃内存)。
- 磁盘:Open WebUI 镜像 + 数据卷预留 5~10 GB;如果上传大量文档进知识库,按文档体积的 2~3 倍预留。
- GPU:Open WebUI 自己不需要 GPU。GPU 是给后端模型用的(Ollama / vLLM)。本地跑 7B 量化模型,建议 8 GB 以上显存;纯 CPU 推理也能用,只是慢。
- 端口:默认用 3000(宿主机)→ 8080(容器内),确认没被占用。
- 网络:如果用云端模型接口,服务器需要能出网访问对应的 API 域名。
分步骤部署
步骤 1:确认 Docker 环境
```bash
docker version
docker compose version
```
两条命令都能输出版本信息即通过。如果提示 permission denied while trying to connect to the Docker daemon socket,说明当前用户不在 docker 组:
```bash
sudo usermod -aG docker $USER
newgrp docker
```
步骤 2:创建工作目录和密钥
```bash
mkdir -p ~/open-webui && cd ~/open-webui
openssl rand -hex 32
```
第二条命令生成的随机字符串就是 WEBUI_SECRET_KEY,必须固定下来。它用于签名登录会话,如果不设置,容器每次重建都会换一个,所有人会被强制登出。把它抄进下一步的配置文件。
步骤 3:编写 docker-compose.yml
在 ~/open-webui 下新建 docker-compose.yml:
```yaml
services:
open-webui:
image: ghcr.io/open-webui/open-webui:<tag>
container_name: open-webui
ports:
- "3000:8080"
volumes:
- open-webui:/app/backend/data
environment:
会话密钥,填上一步生成的值
- WEBUI_SECRET_KEY=把这里换成你的随机字符串
本地 Ollama 地址,见步骤 4
- OLLAMA_BASE_URL=http://host.docker.internal:11434
关闭自助注册,账号由管理员创建
- ENABLE_SIGNUP=false
新用户默认角色:pending / user / admin
- DEFAULT_USER_ROLE=pending
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
volumes:
open-webui:
```
关于 <tag>:官方镜像提供不同标签(CPU 版、CUDA 版等),具体标签名以 Open WebUI 官方文档 / 镜像仓库当前说明为准,选与你的硬件匹配的那个即可。extra_hosts 那行是为了让容器内能用 host.docker.internal 访问宿主机上的 Ollama;Docker Desktop(Mac/Windows)自带该域名,Linux 需要这一行显式声明。
启动:
```bash
docker compose up -d
docker compose ps
```
成功标志:open-webui 状态是 running 或 Up。首次启动拉镜像需要几分钟。
步骤 4:对接本地模型(Ollama)
如果 Ollama 装在宿主机上(不是容器里),它默认只监听 127.0.0.1:11434,容器访问不到。改成监听所有网卡:
```bash
sudo systemctl edit ollama.service
```
在打开的编辑器里填入:
```ini
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
```
保存后重载:
```bash
sudo systemctl daemon-reload
sudo systemctl restart ollama
curl http://localhost:11434/api/tags
```
最后一条能返回 JSON 模型列表即为正常。然后重启 Open WebUI 让配置生效:
```bash
docker compose restart open-webui
```
进网页后台 → 设置 → 连接,Ollama 地址填 http://host.docker.internal:11434,点刷新,能列出模型就说明通了。
> 注意:容器内的 127.0.0.1 指的是容器自己,不是宿主机。这是新手最容易踩的坑。
步骤 5:对接云端模型(OpenAI 兼容接口)
任何兼容 OpenAI 协议的服务都能接:OpenAI、DeepSeek、通义、智谱、硅基流动、自建 vLLM 等。两种方式:
方式一(推荐,改配置不用重启):登录后进入 设置 → 连接 → OpenAI API:
- API Base URL:填到
/v1为止,例如https://api.example.com/v1,不要带/chat/completions - API Key:服务商给的密钥
- 保存后回到模型列表点刷新,出现新模型即可用
方式二(环境变量,适合批量部署):
```yaml
environment:
- OPENAI_API_BASE_URLS=https://api.example.com/v1
- OPENAI_API_KEYS=sk-xxxxxx
```
多组接口用分号 ; 分隔,顺序一一对应。变量名在不同版本可能调整,以官方文档当前版本为准。
步骤 6:创建管理员与多用户
第一个注册的账号会自动成为管理员。如果已经设了 ENABLE_SIGNUP=false,先在 docker-compose.yml 里临时改成 true,注册完管理员再改回来并重启。
之后管理员在 右上角头像 → 管理面板 → 用户 里:
- 新建用户:填邮箱、密码、角色
- 角色说明:
admin管全部;user正常使用;pending需要管理员审批后才能登录(适合开放注册但要把关的场景) - 模型权限:在 管理面板 → 模型 里可以设置某个模型只对部分用户可见,做分级开放
- 配额与速率:按用户设置消息额度,防止个别账号刷爆 API 账单
步骤 7(可选):Ollama 也放进 Compose
不想在宿主机单独装 Ollama,可以合并成一个 Compose 文件:
```yaml
services:
ollama:
image: ollama/ollama:<tag>
container_name: ollama
volumes:
- ollama:/root/.ollama
ports:
- "11434:11434"
需要 GPU 时启用下面这段,并确保已安装 NVIDIA Container Toolkit
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
restart: unless-stopped
open-webui:
image: ghcr.io/open-webui/open-webui:<tag>
container_name: open-webui
ports:
- "3000:8080"
volumes:
- open-webui:/app/backend/data
environment:
- WEBUI_SECRET_KEY=把这里换成你的随机字符串
- OLLAMA_BASE_URL=http://ollama:11434
depends_on:
- ollama
restart: unless-stopped
volumes:
ollama:
open-webui:
```
同一 Compose 网络内,直接用服务名 ollama 当主机名。启动后拉一个模型:
```bash
docker exec -it ollama ollama pull <模型名>
```
模型名以 Ollama 官方模型库当前列表为准。
验证部署是否成功
按顺序检查四件事:
```bash
1. 容器在跑
docker compose ps
2. 端口在监听(应显示 0.0.0.0:3000)
ss -tlnp | grep 3000
3. 健康检查接口(部分版本提供,返回含 status 的 JSON)
curl -s http://localhost:3000/health
4. 启动日志没有持续报错
docker logs --tail 50 open-webui
```
浏览器打开 http://服务器IP:3000,能看到登录/注册页即为部署成功。登录后做一次端到端验证:新建对话 → 顶部选一个模型 → 发一句「用一句话解释什么是AI 词典:向量数据库">向量数据库」→ 有正常流式回复,说明模型链路打通。再上传一个 PDF 到知识库并提问,能引用到文档内容,说明 RAG 链路也正常。
常见报错与解决
1. 报错:Ollama: Connection failed / 日志出现 ECONNREFUSED 127.0.0.1:11434
原因:容器内配置的 Ollama 地址写成了 127.0.0.1,指向的是容器自身而不是宿主机。
解决:
```bash
宿主机安装的 Ollama
sed -i 's|OLLAMA_BASE_URL=.*|OLLAMA_BASE_URL=http://host.docker.internal:11434|' docker-compose.yml
同时确认 Ollama 监听 0.0.0.0,见步骤 4
docker compose up -d
```
2. 报错:bind: address already in use
原因:宿主机 3000 端口被别的程序占用。
解决:换一个宿主机端口,例如改成 - "8080:8080",然后 docker compose up -d,用新端口访问。
3. 报错:重启容器后所有人被登出,或提示会话失效
原因:没有设置 WEBUI_SECRET_KEY,每次重建容器都生成新的签名密钥。
解决:固定一个随机值写进环境变量,之后不要再改动:
```bash
openssl rand -hex 32
把结果填入 WEBUI_SECRET_KEY 后
docker compose up -d
```
4. 报错:上传文档后知识库检索不到内容 / 报 embedding 相关错误
原因:知识库需要嵌入模型。没配嵌入模型时,文档无法被向量化。
解决:在 设置 → 文档 里指定一个嵌入模型;用 Ollama 的话先拉一个嵌入模型:
```bash
ollama pull <嵌入模型名>
```
或用云端嵌入接口并填好 API Key。模型名以对应官方文档为准。
5. 报错:容器启动后立刻退出,日志显示 unable to open database file 或权限错误
原因:数据卷挂载目录权限不对(常见于把宿主机目录直接挂给容器且属主是 root)。
解决:优先使用命名卷(如本文 Compose 中的 open-webui:);如果坚持用宿主机目录:
```bash
sudo chown -R 1000:1000 /path/to/data
docker compose up -d
```
后续维护
备份:所有状态(账号、对话、上传文件、知识库)都在 /app/backend/data 这个卷里。定期打包:
```bash
docker run --rm \
-v open-webui:/data \
-v $(pwd):/backup \
alpine tar czf /backup/open-webui-$(date +%F).tar.gz -C /data .
```
建议放到 crontab 每天跑一次,并确认恢复流程可用(在新机器上解包回卷里,起容器验证登录)。
升级:Open WebUI 迭代较快,升级前先备份数据卷。
```bash
cd ~/open-webui
docker compose pull
docker compose up -d
docker image prune -f
```
跨大版本升级前,建议先看官方 Release Notes 里的破坏性变更说明。
日志与监控:
- 实时看日志:
docker logs -f --tail 100 open-webui - 容器带日志轮转,避免磁盘被写满:
```yaml
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
```
- 用
curl -sf http://localhost:3000/health做存活探测,接进 Uptime Kuma、Prometheus blackbox_exporter 之类的工具。 - 重点盯三件事:磁盘增长(上传文件和向量库)、API 调用量(云端模型的账单)、登录失败次数。
- 安全方面:对外暴露时建议套一层 Nginx/Caddy 做 HTTPS 反代,把
ENABLE_SIGNUP设为false,并在防火墙只放行反代端口,不要把 3000 直接暴露到公网。 - 定期在 管理面板 → 数据库 里清理陈旧对话,或按用户配额控制增长速度。
