最容易先出错的地方,是把 localhost 当成一个全局地址。对运行在 Docker 容器里的 Open WebUI 来说,localhost 指向 Open WebUI 容器自身。它访问宿主机或另一台容器时,都不能继续使用这个地址。常见情况下的地址关系有三种:
| 访问场景 | Open WebUI 访问 Ollama | 浏览器访问 Open WebUI |
|---|---|---|
| Ollama 与 Open WebUI 同处一个 Compose | http://ollama:11434 |
http://127.0.0.1:3000 |
| Ollama 在宿主机 | http://host.docker.internal:11434 |
http://127.0.0.1:3000 |
| 局域网其他设备访问 | 与上面相同 | http://宿主机固定IP:3000 |
如果当前就是“同一个 Compose 部署 Ollama 和 Open WebUI”,先把 Open WebUI 的 OLLAMA_BASE_URL 改成 http://ollama:11434,重新创建 Open WebUI 容器,再把 DeepSeek R1 下载到同一个 Ollama 容器里。docker compose restart 不会重新应用修改后的环境变量,配置变更后应使用 docker compose up -d 重新创建相关容器。
Open WebUI 连 Ollama 时,地址到底该填哪一个?
Compose 里的服务名就是容器网络中的 DNS 名称。只要 Open WebUI 和 Ollama 位于同一个 Compose 项目的默认网络中,ollama 就是比容器 IP 更合适的内部地址。容器重建后 IP 可能变化,但服务名仍然可以解析,因此不应该把 172.x.x.x 之类的容器地址写进配置。
host.docker.internal 是另一种情况:Ollama 直接安装在宿主机上,Open WebUI 则运行在容器中。Windows Docker Desktop 可以使用这个主机名访问宿主机;Linux 原生 Docker Engine 是否可直接使用,取决于当前 Engine 和 Compose 对 host-gateway 的支持,不能把 Windows 上的配置原样当成 Linux 的通用答案。
因此,看到“Open WebUI 连不上 Ollama”时,先问的不是“要不要重装模型”,而是这条地址属于哪个网络命名空间:
Open WebUI 容器 → 同 Compose 的 Ollama:http://ollama:11434
Open WebUI 容器 → 宿主机上的 Ollama:http://host.docker.internal:11434
宿主机浏览器 → Open WebUI:http://127.0.0.1:3000
局域网浏览器 → 宿主机上的 Open WebUI:http://192.168.1.10:3000
前两条是 Open WebUI 后端访问模型使用的地址,最后两条才是用户浏览器访问 Open WebUI 使用的地址。把它们混成一个变量,是连接失败最常见的原因。
Docker Compose 最小配置怎样写,才不会把两个服务接错?
同一个 Compose 中运行 Ollama 和 Open WebUI,可以先使用下面这份只包含必要字段的配置:
services:
ollama:
image: ollama/ollama:latest
environment:
OLLAMA_HOST: 0.0.0.0:11434
volumes:
- ollama-data:/root/.ollama
restart: unless-stopped
open-webui:
image: ghcr.io/open-webui/open-webui:main
environment:
OLLAMA_BASE_URL: http://ollama:11434
volumes:
- open-webui-data:/app/backend/data
ports:
- "3000:8080"
depends_on:
- ollama
restart: unless-stopped
volumes:
ollama-data:
open-webui-data:
这里没有把 Ollama 的 11434 映射到宿主机,因为 Open WebUI 和它已经处于同一个 Compose 网络,不需要额外暴露 Ollama API。OLLAMA_HOST: 0.0.0.0:11434 让 Ollama 在容器内监听可被其他容器访问的地址;OLLAMA_BASE_URL 则明确告诉 Open WebUI 去哪个实例读取模型。
ollama-data 保存模型文件,open-webui-data 保存 Open WebUI 数据。配置正确挂载后,重新创建容器不会因为一次 docker compose down 就丢掉模型和会话;不要随手执行带 -v 的清理命令,因为那会删除项目中的数据卷。
depends_on 只负责安排启动顺序,并不表示 Ollama API 已经初始化完成。Open WebUI 可能在 Ollama 尚未就绪时先启动,因此启动阶段的短暂连接失败不能直接判定为地址错误,需要结合日志和容器内连通性测试继续确认。
另外,示例中的 latest 和 main 都是会移动的镜像标签。正式发布时应按部署当天的 Open WebUI 与 Ollama 官方文档换成确认过的版本标签,最好进一步固定到 digest;否则下一次拉取可能得到不同的软件版本和配置行为。
DeepSeek R1 已经 pull,为什么 Open WebUI 里还是没有模型?
在同 Compose 部署中,模型必须下载到 Compose 里的 Ollama 容器。宿主机上执行过的 ollama pull,不一定属于这个容器所连接的实例。
先在 Ollama 服务内部完成下载、查看和最小测试:
docker compose exec ollama ollama pull deepseek-r1:7b
docker compose exec ollama ollama list
docker compose exec ollama ollama run deepseek-r1:7b
deepseek-r1:7b 只是当前示例标签,实际可用标签应以 Ollama 模型列表为准。ollama list 用于确认模型确实存在,ollama run 则用于确认当前实例不只是能列出模型,而是能真正加载并生成内容。
如果 ollama run 成功,但 Open WebUI 仍然没有模型,优先检查两个实例是否一致。可以分别执行:
ollama list
docker compose exec ollama ollama list
宿主机和容器返回的模型列表不同,通常意味着同时运行了原生 Ollama 与容器 Ollama。此时 Open WebUI 只会连接 OLLAMA_BASE_URL 指向的实例,不会自动汇总两个实例里的模型。
第二个检查点是数据卷。确认渲染后的 Compose 配置仍然挂载了 ollama-data:
docker compose config
如果之前是从宿主机原生 Ollama 下载模型,后来切换成纯 Compose 部署,那么模型并没有自动迁移到 ollama-data。需要先决定保留哪个实例,再迁移模型,不要在两边同时维护一份同名模型后继续猜测 Open WebUI 实际连接了谁。
容器明明显示 Up,为什么 Open WebUI 还是连不上?
“容器显示 Up”只能证明主进程没有退出,不能证明 Ollama 已经可以处理模型请求。排查时按配置、状态、连通性三层证据往下走:
docker compose config
docker compose ps
docker compose logs --tail=100 ollama
docker compose logs --tail=100 open-webui
docker compose config 显示最终生效的配置和环境变量,可以排除 YAML 缩进、环境变量名称或旧项目配置的问题。不过它也可能展开敏感配置,不适合原样贴到公开工单里。
docker compose ps 用来确认服务是否仍在运行、端口是否发布;日志则分别回答两个问题:Ollama 是否成功加载模型,Open WebUI 是否正在请求错误的地址。
如果需要从 Open WebUI 容器内部探测 Ollama,先检查镜像里实际提供了哪些 HTTP 工具,不要预设 curl 一定存在:
docker compose exec open-webui sh -lc 'command -v curl || command -v wget || command -v python'
如果存在 curl,可以测试服务名和端口:
docker compose exec open-webui curl -fsS http://ollama:11434/api/tags
如果只有 Python,则可以使用容器内的 Python 发请求:
docker compose exec open-webui python -c "import urllib.request; print(urllib.request.urlopen('http://ollama:11434/api/tags', timeout=5).status)"
这一步比从宿主机测试更有针对性。宿主机能够访问 Ollama,不代表 Open WebUI 容器也能通过 Compose 服务名访问。反过来,容器内能够访问 /api/tags,但返回的模型列表里没有刚下载的模型,就应继续核对模型实例和数据卷,而不是继续修改 OLLAMA_BASE_URL。
固定访问地址,到底要固定容器名、端口还是 IP?
真正需要固定的是三层契约,而不是某个孤立 URL。
第一层是 Open WebUI 到 Ollama 的内部地址,使用 Compose 服务名 http://ollama:11434。容器 IP 和自动生成的容器名都不适合作为长期配置。
第二层是宿主机到 Open WebUI 的端口映射。Open WebUI 容器仍监听 8080,宿主机通过 3000 对外提供访问:
ports:
- "3000:8080"
第三层才是客户端使用的宿主机 IP 或 DNS。局域网访问时,可以使用路由器的 DHCP 地址保留、静态地址,或者局域网 DNS,将域名解析到运行 Compose 的主机。
如果只允许宿主机本机访问,可以收紧端口绑定:
ports:
- "127.0.0.1:3000:8080"
如果宿主机固定使用 192.168.1.10,也可以绑定到该地址:
ports:
- "192.168.1.10:3000:8080"
这两种写法按用途二选一。绑定固定内网 IP 的前提是这个 IP 确实配置在宿主机网卡上;如果 DHCP 更换了地址,容器可能无法按原配置启动。实际使用中,更稳妥的做法通常是保留宿主机端口映射,再通过静态租约或 DNS 保证客户端看到的地址稳定。
局域网其他设备访问时,浏览器应打开:
http://192.168.1.10:3000
而不是容器内部的 8080。如果本机能开、局域网打不开,还要依次检查端口绑定是否包含局域网网卡、宿主机防火墙是否放行入站 TCP 3000,以及客户端是否仍在使用旧 IP。
公网固定域名不属于 Compose 的职责范围。不要把 Ollama 的 11434 直接暴露到公网;Open WebUI 的宿主机端口可以只绑定回环地址,再由宿主机上的反向代理提供 HTTPS、访问控制和证书。如果反向代理本身也是 Compose 容器,则应让两者进入同一网络,通过服务名通信,而不是让代理容器访问宿主机自己的 127.0.0.1。
已经用 Python 3.11 跑过 open-webui serve,再上 Compose 为什么会更乱?
Python 3.11、open-webui serve、Ollama、DeepSeek R1 和固定访问地址并不是一条安装链上的连续步骤。原生安装和 Compose 部署是两套独立实例。
原生路线是:
pip install open-webui
open-webui serve
这条路线的 Open WebUI 和 Ollama 都运行在宿主机时,http://127.0.0.1:11434 对 Ollama 是成立的;换成 Compose 后,Open WebUI 进程进入了容器,localhost 的含义随之改变。环境变量名称相同,并不代表它们解析到同一个地址。
如果 pip 实例和 Compose 实例同时运行,先查清楚谁占用了端口:
docker ps --format "table {{.Names}}\t{{.Ports}}"
sudo ss -ltnp | grep -E ':(3000|8080|11434)\b'
Windows 主机可以改用:
netstat -ano | findstr "3000 8080 11434"
排查时先确认浏览器实际连接的是哪一个 Open WebUI,再确认它使用的 OLLAMA_BASE_URL。不要在两个实例之间反复修改同一个地址变量,它们既不共享进程,也不默认共享数据库或模型数据。
同理,不要为了“清干净”直接执行 docker compose down -v。这会把模型卷和 Open WebUI 数据卷一起删除;如果旧实例仍有排查价值,先保留日志、配置和数据卷,再决定清理范围。
Windows + WSL2 和 NVIDIA GPU,还要检查哪些东西?
Windows 10/11 使用 Docker Desktop 时,应先确认 Docker Desktop 已启用 WSL2 后端,并确认实际运行的容器确实使用了这个后端。Windows 和 Linux 容器在网络、GPU 与挂载行为上并不完全相同,不能只看 Docker Desktop 正常启动就推断所有资源都可用。
模型数据尽量使用前面的命名卷,或者放在 WSL2 文件系统内部。若把模型目录绑定到 /mnt/c/...,Windows 与 WSL2 之间的跨文件系统访问会带来额外 I/O 成本,模型加载和读取可能明显变慢。使用 Docker Desktop 管理的数据卷可以避开这类跨文件系统路径,但迁移机器时仍要单独备份卷内容。
Linux 上的 NVIDIA GPU 容器还需要宿主机驱动、对应工具链以及容器 GPU 设备请求。常见的 Compose 结构如下,实际字段和支持情况应按当前 Docker Compose、NVIDIA 容器工具链文档确认:
services:
ollama:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
Windows Docker Desktop 的 WSL2 后端也需要匹配的主机驱动和 GPU 支持环境,不能仅凭 Compose 中出现 GPU 配置就认为设备已经透传成功。
验证时先查看 Ollama 容器日志,再检查已加载模型使用的处理设备:
docker compose logs --tail=100 ollama
docker compose exec ollama ollama ps
不同版本的 ollama ps 输出格式可能变化,应根据当前输出确认模型是否仍在 CPU 上运行。即使 GPU 已经可见,模型大小、显存容量、量化方式和上下文长度仍会影响速度,不能承诺同一模型在所有硬件上获得相同表现。
端口占用、模型不显示、局域网打不开,按什么顺序查最省时间?
| 现象 | 优先检查 |
|---|---|
| Open WebUI 无法连接模型 | OLLAMA_BASE_URL、Compose 服务名、Ollama 日志 |
| Ollama 中有模型但界面没有 | 是否为同一个实例、模型是否写入当前数据卷 |
| 本机能访问、局域网不能访问 | 主机端口绑定、监听地址、防火墙和内网 IP |
| 3000 端口被占用 | pip 实例、其他容器及旧 Compose 项目 |
| 重启后模型或会话消失 | Ollama 模型卷与 Open WebUI 数据卷是否正确挂载 |
| 容器运行但没有 GPU | NVIDIA 驱动、容器工具链和 GPU 设备请求 |
实际排查时,先用 docker compose config 确认地址和卷配置,再用 docker compose ps、日志确认进程状态,然后从 Open WebUI 容器内部探测 Ollama,最后才检查浏览器、局域网和公网入口。地址、服务名和模型实例是同一条链路上的三个检查点,不要只盯着其中一个。












暂无评论内容