1. 为什么要在 Docker 里跑 OpenClaw + 本地 Qwen3.5 9B
如果你正在找一套「本地模型 + 容器化 Agent 框架」的组合方案,OpenClaw 加 Ollama 加 Qwen3.5 9B 是最近被问得比较多的一条链路。OpenClaw 是一个可以容器化运行的 Agent 网关,提供 Web UI、工作区挂载和工具调用能力;Ollama 负责在本地把 Qwen3.5 9B 这类模型跑起来;TaoToken 则作为统一的 Key 与 API 通道,把本地推理和外部模型调用收敛到一套凭证体系里。适合谁?适合手上有 NVIDIA 显卡、想在自己机器上做本地推理验证、又不想把配置散落在多个工具里的开发者。
我这次的环境是 Ubuntu 24.04.2 LTS,显卡 16GB 显存,驱动 535 以上,内存 32GB,磁盘预留 40GB。整套流程分三段:先用 Docker 起 Ollama 并拉取 qwen3.5:9b-q8_0,再用 docker-compose 起 OpenClaw 并写好 config.toml,最后用一次对话请求验证本地推理和 TaoToken 通道是否都通。下面每一步都给可复制的命令和配置骨架,你照着改路径就能跑。
2. 前置准备:Docker、GPU 运行时与 TaoToken Key
2.1 确认 Docker 与 NVIDIA 容器运行时
先确认 Docker 在:
docker -v如果没有输出,用官方脚本装:
curl -fsSL https://get.docker.com | sh sudo systemctl start docker sudo systemctl enable dockerGPU 能不能被容器用,取决于 NVIDIA Container Toolkit。先看驱动:
nvidia-smi能看到驱动版本和显卡型号就说明驱动没问题。然后确认容器运行时:
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi如果这条命令报could not select device driver "" with capabilities: [[gpu]],说明 toolkit 没配好,需要先按 NVIDIA 官方文档把nvidia-container-toolkit装好并重启 Docker。这一步不通过,后面 Ollama 用不上 GPU,Qwen3.5 9B 会退化到 CPU 推理,速度差一个量级。
2.2 拿 TaoToken Key 与确认接入地址
TaoToken 在这里的角色是统一 Key 和 API 通道。你需要在控制台创建一个 API Key,然后把它写进 OpenClaw 的 config.toml。入口在这里:
- 控制台:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_docker_qwen
- API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_docker_qwen
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_docker_qwen
API 基地址统一用https://taotoken.net/api,不要加 UTM 参数。Key 形如sk-开头的一串字符,创建后只显示一次,先复制到安全的地方。如果你后面还要跑长期编码或 Agent 任务,可以顺带看一下 Coding Plan 页面,把额度规划清楚:
- Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_docker_qwen
3. 可复制配置:docker-compose 起 Ollama 与 OpenClaw
3.1 目录结构与 docker-compose.yml
我习惯把两个服务放在同一个 compose 文件里,网络用默认 bridge,Ollama 暴露 11434,OpenClaw 暴露 18789。先建目录:
mkdir -p ~/openclaw-stack && cd ~/openclaw-stack然后写docker-compose.yml:
services: ollama: image: ollama/ollama:latest container_name: ollama restart: always ports: - "11434:11434" volumes: - ollama-data:/root/.ollama deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] openclaw: image: ghcr.io/openclaw/openclaw:latest container_name: openclaw restart: unless-stopped user: root network_mode: host volumes: - openclaw-data:/root/.openclaw - ./workspace:/root/.openclaw/workspace - ./config.toml:/root/.openclaw/config.toml - /var/run/docker.sock:/var/run/docker.sock depends_on: - ollama volumes: ollama-data: openclaw-data:几个关键点说明一下。deploy.resources.reservations.devices是 compose 里启用 GPU 的写法,等价于--gpus all。OpenClaw 用network_mode: host,这样它访问 Ollama 可以直接写127.0.0.1:11434,不用去猜容器 IP。/var/run/docker.sock挂进去是为了让 OpenClaw 能调用宿主机 Docker,有安全风险,只建议在你自己信任的本机用。
3.2 config.toml 骨架:把本地 Ollama 和 TaoToken 都写进去
在~/openclaw-stack下建config.toml:
[gateway] bind = "0.0.0.0:18789" auth_token = "换成你自己的GatewayToken" [[providers]] id = "ollama" type = "openai-compatible" base_url = "http://127.0.0.1:11434/v1" api_key = "sk-local-no-auth" default_model = "qwen3.5:9b-q8_0" [[providers]] id = "taotoken" type = "openai-compatible" base_url = "https://taotoken.net/api" api_key = "sk-你的TaoTokenKey" default_model = "qwen3.5-9b" [workspace] path = "/root/.openclaw/workspace"这里有两个 provider。ollama指向本地 11434,api_key随便填,因为本地 Ollama 默认不鉴权。taotoken指向https://taotoken.net/api,Key 换成你在控制台创建的那一串。default_model先按占位写,实际模型名以ollama list输出为准。Gateway 的auth_token就是 Web UI 登录口令,自己设一个足够长的字符串。
3.3 拉取 Qwen3.5 9B 并确认模型名
compose 起来之后,模型要在 Ollama 容器里拉:
docker compose up -d ollama docker exec -it ollama ollama pull qwen3.5:9b-q8_0拉完确认:
docker exec -it ollama ollama list输出里会有一行类似qwen3.5:9b-q8_0的名字,把它原样填回 config.toml 的default_model。如果拉取时报模型不存在,先升级镜像再重试:
docker pull ollama/ollama:latest docker compose up -d --force-recreate ollama数据卷ollama-data会保留,模型不会丢。
4. 验证请求:一次对话打通本地推理与 TaoToken 通道
4.1 先验证 Ollama 本地推理
在起 OpenClaw 之前,先单独确认 Ollama 能出结果:
curl http://127.0.0.1:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3.5:9b-q8_0", "messages": [{"role": "user", "content": "用一句话说明你是什么模型"}] }'返回 JSON 里有choices[0].message.content就说明本地推理通了。同时开另一个终端跑watch -n 1 nvidia-smi,发请求时应该能看到显存占用上涨、GPU 利用率有波动。如果显存没变化,多半是 GPU 没被容器用上,回到 2.1 检查 toolkit。
4.2 再验证 TaoToken 通道
用同一个 OpenAI 兼容格式打 TaoToken:
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的TaoTokenKey" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3.5-9b", "messages": [{"role": "user", "content": "回复 ok 即可"}] }'返回正常就说明 Key 和通道都没问题。如果这里报 401,检查 Key 是否复制完整;报 404 检查模型名是否在 TaoToken 支持的列表里。模型对话的在线验证入口在这里,可以对照着看返回结构:
- 模型对话:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_docker_qwen
4.3 起 OpenClaw 并在 Web UI 里发消息
两条通道都通之后,把 OpenClaw 拉起来:
docker compose up -d openclaw docker logs -f openclaw日志里出现 gateway 监听 18789 就绪后,浏览器打开http://127.0.0.1:18789,填入 config.toml 里的auth_token。进入对话界面后,provider 选ollama,模型选qwen3.5:9b-q8_0,发一条消息。能收到回复,同时nvidia-smi有占用,就说明「OpenClaw → Ollama → Qwen3.5 9B」这条本地链路完整打通。再把 provider 切到taotoken,发同样的消息,验证统一 Key 通道也通。
5. 本篇常见错排查
5.1 端口 11434 被系统服务版 Ollama 抢占
如果你之前用systemctl装过 Ollama,它会直接占用 11434,导致 Docker 版映射失败或请求打到错误的服务上。先停掉:
sudo systemctl stop ollama sudo systemctl disable ollama提示Unit ollama.service not found说明没装过,忽略即可。
5.2 在宿主机直接跑 ollama pull 报 command not found
Docker 版 Ollama 的命令行在容器里,宿主机没有ollama这个命令。所有 pull、list、run 都要加docker exec -it ollama前缀。除非你额外在宿主机装了 Ollama CLI,否则别直接在宿主机敲。
5.3 OpenClaw 报 EACCES 或 Web UI 校验失败
典型原因是 configure 和 run 用了不同用户。root 的配置目录是/root/.openclaw,非 root 的 node 用户是/home/node/.openclaw。compose 里我统一写了user: root,挂载也按/root/.openclaw来,保持一致就不会出这个问题。如果你改成 node 用户,挂载路径和 config.toml 位置都要同步改。
5.4 Web UI 报 No API key found for provider
这个报错通常出现在 provider 的id和 config.toml 里引用的名字对不上。检查[[providers]]下的id是否写成了ollama,以及 Web UI 里选的 provider 是否和它一致。名字拼错、大小写不一致都会触发。
5.5 模型名写错导致 404
default_model必须和ollama list输出的名字完全一致,包括:9b-q8_0这种 tag。少写 tag 或写成qwen3.5:9b都可能找不到。改完 config.toml 后重启 OpenClaw:
docker compose restart openclaw6. 后续怎么用:把本地推理和统一通道固定下来
这套配置跑通之后,日常使用就是docker compose up -d起服务,Web UI 里切 provider 做本地或通道调用。如果你后面要跑长期编码任务或 Agent 工作流,建议把 Coding Plan 的额度规划一下,避免本地和通道两边混着用导致 Key 管理混乱:
- Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_docker_qwen
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=openclaw_docker_qwen
一个实用技巧:把config.toml里的auth_token和 TaoToken Key 用环境变量注入,别硬编码在文件里,compose 里加env_file就行。这样换机器或分享配置时不会泄露凭证。另外ollama-data和openclaw-data两个卷定期备份,模型和配置都能快速恢复。