# 小米路由器 Docker-compose 部署 Ollama 大模型:常见报错与排查
## 背景
小米路由器(基于 OpenWrt 定制)运行 Docker 时,docker-compose 配置与标准 Linux 存在差异。本文聚焦实操中最高频的三类报错,提供可直接复用的修复方案。
> 测试环境:小米 BE6500 Pro(OpenWrt 23.05),docker 24.0.7,docker-compose v2.23.0
—
## 问题一:network bridge 冲突导致容器无法启动
### 现象
“`bash
docker-compose up -d
# Error response from daemon: network bridge is not found
“`
### 可能原因
OpenWrt 的网络架构与桌面 Linux 不同,默认 bridge 由系统管理,docker-compose 手动定义的 `driver: bridge` 可能与预置网络冲突。
### 排查命令
“`bash
# 查看当前 Docker 网络
docker network ls
# 查看已存在的网桥
ip link show | grep -E ‘docker|br-lan|br-‘
# 查看 Docker 守护进程配置
cat /etc/docker/daemon.json
“`
### 解决步骤
1. 检查当前网络状态
“`bash
ip link show | grep docker
# 通常能看到 docker0 已存在
docker network ls
“`
2. 修改 docker-compose.yml,使用默认网络而非手动创建
“`yaml
# 错误写法
networks:
default:
driver: bridge
# 正确写法(省略 networks 块,让 Docker 自动管理)
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
– “11434:11434”
volumes:
– ./ollama_data:/root/.ollama
environment:
– OLLAMA_HOST=0.0.0.0
“`
3. 如需手动网络,指定 subnet 避开 OpenWrt 段
“`yaml
networks:
default:
driver: bridge
ipam:
config:
– subnet: 172.28.0.0/16
“`
### 进阶:多容器场景下的网络配置
若同时部署 Ollama + OpenWebUI,建议创建专用网络实现容器互联:
“`yaml
version: ‘3.8’
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
– “11434:11434” # 对外暴露
volumes:
– ./ollama_data:/root/.ollama
environment:
– OLLAMA_HOST=0.0.0.0
– OLLAMA_ORIGINS=* # 允许跨域访问
networks:
– ollama-net
openwebui:
image: ghcr.io/open-webui/open-webui:main
container_name: openwebui
restart: unless-stopped
ports:
– “8080:8080”
environment:
– OLLAMA_BASE_URL=http://ollama:11434
depends_on:
– ollama
networks:
– ollama-net
networks:
ollama-net:
driver: bridge
ipam:
config:
– subnet: 172.28.0.0/16
“`
### 常见变体报错
| 报错信息 | 原因 | 解决方案 |
|———|——|———|
| `network bridge not found` | 手动指定了不存在的网络名 | 改用默认网络或先 `docker network create` |
| `port is already allocated` | 11434端口被占用 | 换端口如 `11435:11434` 或 kill 占用进程 |
| `driver failed programming external connectivity` | iptables 规则冲突 | 重启 Docker 服务 `service docker restart` |
—
## 问题二:存储卷路径权限拒绝
### 现象
“`bash
docker-compose up -d
# Error response from daemon: Access denied on path /root/.ollama
“`
### 可能原因
OpenWrt 的 ext4/uofat 文件系统默认以 `nobody` 用户运行容器,而宿主机目录归属 `root`,导致 uid 100000+ 的容器内用户无写权限。
### 原理说明
Docker 容器默认以 `ollama` 服务用户(uid 1000)运行,但小米路由器 OpenWrt 的存储路径(通常是 `/mnt/storage`)由 Samba/NFS 服务以 `nobody` 身份共享。当容器内进程尝试写入挂载卷时,实际以容器内 uid(如 1000)向宿主机的 `nobody:nogroup` 目录写入,触发 POSIX 权限拒绝。
### 排查命令
“`bash
# 查看目录归属
ls -la /mnt/storage/
# 查看容器内默认用户
docker exec ollama id
# 查看当前用户映射
cat /etc/subuid
cat /etc/subgid
“`
### 解决步骤
1. 创建目录并授权
“`bash
mkdir -p /mnt/storage/ollama_data
chmod -R 777 /mnt/storage/ollama_data
“`
2. 在 compose 文件中显式指定用户(关键)
“`yaml
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
– “11434:11434”
volumes:
– /mnt/storage/ollama_data:/root/.ollama
environment:
– OLLAMA_HOST=0.0.0.0
user: “0:0” # 强制 root 权限解决写入问题
“`
3. 若仍报错,改用 tmpfs 临时存储测试
“`yaml
volumes:
– type: tmpfs
target: /root/.ollama
“`
### 进阶方案:使用命名卷
ext4/uopart 文件夹权限问题可通过 Docker 命名卷绕过:
“`yaml
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
volumes:
– ollama_data:/root/.ollama
volumes:
ollama_data:
driver: local
driver_opts:
type: none
o: bind
device: /mnt/storage/ollama_data
“`
### 权限问题自查清单
– [ ] 宿主机目录已创建
– [ ] 目录权限为 777 或 755
– [ ] compose 文件中显式指定 `user: “0:0″`
– [ ] 尝试重启 Docker 服务
– [ ] 检查是否是 uopart 文件系统的特殊情况
—
## 问题三:内存不足导致 OOM Kill
### 现象
“`bash
docker-compose up -d
# dmesg: oom-kill: nvidia-gpu, uid=65534 oom_adj=0
# 或者容器状态显示 Exited (137)
“`
### 可能原因
小米路由器通常只有 512MB–1GB 内存,跑量化模型(如 Q4_K_M)勉强可以,但加载 7B 以上模型不加 swap 会直接被内核杀掉。
### 原理说明
Linux OOM Killer(Out-of-Memory Killer)是内核机制,当物理内存 + swap 全部耗尽时,内核会根据 `oom_score` 杀掉得分最高的进程。Docker 容器受 `mem_limit` 约束,但若未设置限制或 swap 缺失,宿主机本身会被 OOM。路由器场景下,OpenWrt 系统服务(dnsmasq、uhttpd 等)已经占用 200-300MB 内存,留给 Docker 的空间非常有限。
### 排查命令
“`bash
# 检查内存使用
free -m
# 检查 swap 状态
swapon -s
# 查看 dmesg 中的 OOM 日志
dmesg | grep -i oom
# 查看容器内存限制
docker stats –no-stream
# 实时监控内存
watch -n 1 ‘free -m’
“`
### 解决步骤
1. 检查可用内存与 swap
“`bash
free -m
swapon -s
“`
2. 创建 swap 文件(路由器通常未配置)
“`bash
dd if=/dev/zero of=/mnt/storage/swapfile bs=1M count=2048
chmod 600 /mnt/storage/swapfile
mkswap /mnt/storage/swapfile
swapon /mnt/storage/swapfile
“`
3. 添加 docker-compose 内存限制,保守配置
“`yaml
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
– “11434:11434”
volumes:
– /mnt/storage/ollama_data:/root/.ollama
environment:
– OLLAMA_HOST=0.0.0.0
– OLLAMA_NUM_PARALLEL=2 # 限制并发数
– OLLAMA_MAX_LOADED_MODELS=1 # 最多同时加载1个模型
mem_limit: 750m # 硬性内存上限
mem_reservation: 512m
user: “0:0”
“`
4. 拉取适合路由器的小模型
“`bash
docker exec -it ollama ollama pull phi3:mini # 2.3GB,适合512MB内存
docker exec -it ollama ollama pull llama3.2:1b # 1.3GB,量化后更小
“`
### 路由器内存配置参考表
| 路由器型号 | 内存 | 推荐模型 | 最大并发 |
|———–|——|———|———|
| 小米 AX3600 | 512MB | phi3:mini, llama3.2:1b | 1 |
| 小米 AX9000 | 1GB | qwen2.5:3b, llama3.2:3b | 1-2 |
| 小米 BE6500 Pro | 1GB | qwen2.5:3b, mistral:7b (Q4) | 2 |
| 小米万兆路由器 | 2GB | llama3.2:7b, mistral:7b | 3 |
—
## 可用的 docker-compose 完整配置
“`yaml
version: ‘3.8’
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
– “11434:11434”
volumes:
– /mnt/storage/ollama_data:/root/.ollama
environment:
– OLLAMA_HOST=0.0.0.0
– OLLAMA_NUM_PARALLEL=2
– OLLAMA_MAX_LOADED_MODELS=1
mem_limit: 750m
mem_reservation: 512m
user: “0:0”
“`
部署后通过 `http://路由器IP:11434` 访问 API,配合 OpenWebUI 可实现 ChatGPT 风格界面。
—
## 进阶优化:Ollama 性能调优
### 1. GPU 加速(如路由器支持)
部分高端路由器内置 GPU 或可通过 USB 外接 GPU:
“`yaml
services:
ollama:
deploy:
resources:
reservations:
devices:
– driver: nvidia
count: 1
capabilities: [gpu]
“`
### 2. 模型量化级别选择
| 量化方式 | 压缩率 | 内存占用 | 质量损失 | 推荐场景 |
|———|——-|———|———|———|
| FP16 | 基准 | 高 | 无 | 科研测试 |
| Q4_K_M | 60% | 中 | 极小 | 路由器推荐 |
| Q5_K_S | 50% | 低 | 小 | 极致省内存 |
| Q8_0 | 40% | 最低 | 无 | 极致省内存 |
### 3. 预加载模型减少每次响应延迟
“`yaml
services:
ollama:
command: –serve –model phi3:mini
“`
—
## 常见问题 FAQ
Q1: 容器启动正常但 API 无响应?
检查防火墙设置,OpenWrt 默认不允许外部访问 11434 端口:
“`bash
uci add firewall rule
uci set firewall.@rule[-1].name=’Allow-Ollama’
uci set firewall.@rule[-1].src=’wan’
uci set firewall.@rule[-1].dest_port=’11434′
uci set firewall.@rule[-1].proto=’tcp’
uci set firewall.@rule[-1].target=’ACCEPT’
uci commit firewall
service firewall restart
“`
Q2: 模型下载速度极慢?
路由器网络 QoS 可能限速,换用国内镜像或开代理:
“`bash
export HTTPS_PROXY=http://192.168.0.66:7890
docker exec ollama bash -c “echo ‘Environment=https_proxy’ >> /etc/environment”
“`
Q3: 容器重启后模型丢失?
确保挂载卷路径正确,检查 `docker volume ls` 确认命名卷存在。
Q4: 如何查看 Ollama 运行时日志?
“`bash
docker logs -f ollama
docker exec ollama ollama list # 查看已下载模型
docker exec ollama ollama ps # 查看运行中的模型
“`
—
## 小结
小米路由器跑 Docker 模型的三大门槛:网络配置差异、权限路径问题、硬件资源硬上限。核心建议:
1. 优先使用 Docker 默认网络,避开 bridge 冲突
2. 显式指定 `user: “0:0″` 解决卷写入权限
3. 必开 swap,并限制并发数与内存,避免 OOM
4. 模型选型上,路由器的 1GB 内存瓶颈决定了 3B 以下的 quantized 模型是更务实的选择
相关阅读:手机868 深圳报价