
1. 为什么要把 OpenClaw 塞进容器里跑OpenClaw 这个项目最近在 Agent 圈子里讨论度不低它把 gateway网关和 controlUi控制台拆成两个独立组件一个负责模型请求的路由与转发一个负责可视化操作和会话管理。听起来挺清晰但真到部署环节很多人第一步就卡住了Node 版本不对、全局包权限报错、gateway 起来了 controlUi 连不上、设备配对一直 pending。我试过在裸机上折腾了两小时最后还是决定用 docker-compose 把整条链路封起来。容器部署 OpenClaw 的核心价值在于把 Node 运行时、全局 npm 包、配置文件路径、端口映射全部固化到镜像和 compose 文件里换台机器docker-compose up -d --build就能复现。更重要的是gateway 和 controlUi 之间的通信走的是容器内网络你不需要在宿主机上装一堆依赖也不用担心~/.openclaw/openclaw.json被不同用户权限搞乱。这篇文章面向的是想快速跑通 OpenClaw 全链路的开发者尤其是那些准备把模型调用统一走 TaoToken 通道的人。我会给出可直接复制的 docker-compose 配置、环境变量设置、gateway 路由参数以及 controlUi 打开后如何验证请求是否正常返回。整个过程不需要你提前理解 OpenClaw 的内部架构跟着步骤走就行。先说清楚两个组件的分工。gateway 是实际处理模型请求的服务它监听一个端口默认 18789接收来自 controlUi 或其他客户端的调用然后根据配置把请求转发到上游模型 API。controlUi 是一个 Web 界面你可以在浏览器里打开它配置令牌、发起对话、查看设备配对状态。两者通过 gateway 暴露的 HTTP 接口通信所以容器网络里 gateway 必须先起来controlUi 才能连上。用 docker-compose 的好处是你可以把 gateway 和 controlUi 定义成两个 service用depends_on控制启动顺序用volumes把配置文件挂进去用ports把 controlUi 的 Web 端口暴露给宿主机。这样每次调试只需要改 compose 文件或环境变量不用进容器手动改配置。还有一个容易被忽略的点OpenClaw 的设备配对机制。第一次用 controlUi 连接 gateway 时gateway 会生成一个待批准的设备请求你需要在容器内执行openclaw devices approve requestId才能完成配对。这个步骤在裸机部署时经常因为权限或路径问题失败但在容器里只要 gateway 进程在运行配对命令就能正常执行。所以整体思路是先用 docker-compose 把 gateway 和 controlUi 的容器跑起来然后在容器内安装 OpenClaw CLI、启动 gateway、配置 controlUi 的令牌最后在宿主机浏览器里打开 controlUi 完成设备配对。模型调用统一走 TaoToken 的 Key 和 API 通道这样你不需要在容器里配一堆上游厂商的密钥只需要一个 TaoToken 的 Key 就能切换不同模型。2. TaoToken 前置准备Key、Base URL 与模型 ID 怎么拿在写 docker-compose 之前你需要先把 TaoToken 的接入信息准备好。这部分不复杂但顺序不能乱否则后面 gateway 启动时会因为缺少环境变量而报错。首先打开 TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content注册并登录后进入控制台。如果你已经有账号直接进 console 页面。在控制台左侧找到「API Keys」或「密钥管理」点进去创建一个新的 Key。创建时建议给 Key 起一个能识别用途的名字比如openclaw-gateway这样以后排查问题时能快速定位是哪个服务在用。创建完成后你会看到一串以sk-开头的字符串这就是你的 API Key。复制下来保存到安全的地方因为页面刷新后可能不再完整显示。这个 Key 后面会写进 docker-compose 的环境变量里gateway 用它来调用 TaoToken 的模型接口。接下来确认 Base URL。TaoToken 的 API 地址是https://taotoken.net/api注意这里不要加 UTM 参数直接写这个地址就行。gateway 在转发请求时会把 Base URL 和具体的模型路径拼接起来所以你在配置里只需要填这个根地址。模型 ID 这块TaoToken 支持多种模型你可以在控制台的模型列表里看到可用的模型标识。常见的比如claude-sonnet-4-20250514、gpt-4o等具体以你控制台显示的为准。选一个你常用的模型 ID后面在 gateway 的路由配置里会用到。如果你打算长期跑 Agent 或编码任务可以考虑开通 Coding Plan这样在调用频率和额度上会更宽松。入口在控制台的套餐页面按需选择就行。对于只是验证链路的场景普通按量计费的 Key 就够用了。还有一个细节TaoToken 的 API 文档里有详细的请求示例和参数说明建议在配置 gateway 之前先扫一眼文档确认你用的模型 ID 和请求格式。文档入口在控制台顶部导航或官网的「文档」链接里。这样后面 gateway 报错时你能快速判断是 Key 问题、Base URL 问题还是模型 ID 写错了。把这三样东西准备好API Key、Base URLhttps://taotoken.net/api、Model ID。接下来就可以写 docker-compose 文件了。3. 可复制的 docker-compose 配置与 gateway 路由设置这一节是整篇文章的核心我会给出完整的 docker-compose.yml、环境变量文件、gateway 配置文件以及 controlUi 的 settings 片段。你只需要把 TaoToken 的 Key 和模型 ID 替换成自己的就能直接跑起来。先看目录结构。建议在宿主机上建一个项目目录比如openclaw-deploy里面放以下文件openclaw-deploy/ ├── docker-compose.yml ├── .env ├── config/ │ └── openclaw.json └── Dockerfiledocker-compose.yml定义两个 servicegateway和controlui。gateway 负责跑 OpenClaw 的网关进程controlui 负责跑 Web 控制台。两者共享一个自定义网络这样 controlui 可以通过服务名访问 gateway。version: 3.9 services: gateway: build: context: . dockerfile: Dockerfile container_name: openclaw-gateway restart: unless-stopped env_file: - .env volumes: - ./config:/root/.openclaw - ./logs:/var/log/openclaw ports: - 18789:18789 networks: - openclaw-net command: sh -c openclaw gateway run --bind lan --port 18789 /var/log/openclaw/gateway.log 21 controlui: build: context: . dockerfile: Dockerfile container_name: openclaw-controlui restart: unless-stopped env_file: - .env volumes: - ./config:/root/.openclaw ports: - 3000:3000 networks: - openclaw-net depends_on: - gateway command: sh -c openclaw controlui run --port 3000 --gateway http://gateway:18789 networks: openclaw-net: driver: bridge这里有几个关键点。gateway 的--bind lan表示监听所有网络接口这样容器内的 controlui 和宿主机都能访问。端口 18789 映射到宿主机方便你直接用 curl 测试。controlui 的--gateway参数指向http://gateway:18789这里用的是 Docker 内部的服务名解析不需要写 IP。Dockerfile负责安装 Node 和 OpenClaw CLIFROM node:20-slim RUN apt-get update apt-get install -y \ curl \ ca-certificates \ rm -rf /var/lib/apt/lists/* RUN npm install -g openclawlatest WORKDIR /root EXPOSE 18789 3000 CMD [openclaw, --help].env文件放 TaoToken 的接入信息TAOTOKEN_API_KEYsk-你的实际Key TAOTOKEN_BASE_URLhttps://taotoken.net/api TAOTOKEN_MODEL_IDclaude-sonnet-4-20250514 OPENCLAW_GATEWAY_TOKENyour-gateway-token-hereOPENCLAW_GATEWAY_TOKEN是 controlUi 连接 gateway 时用的令牌你可以自己生成一个随机字符串比如用openssl rand -hex 16。config/openclaw.json是 gateway 的核心配置文件定义模型路由和 controlUi 的接入参数{ gateway: { bind: lan, port: 18789, token: your-gateway-token-here }, controlUi: { enabled: true, gatewayUrl: http://gateway:18789, token: your-gateway-token-here }, models: { default: { provider: taotoken, baseUrl: https://taotoken.net/api, apiKey: sk-你的实际Key, modelId: claude-sonnet-4-20250514 } }, routes: [ { path: /v1/chat/completions, target: taotoken, model: claude-sonnet-4-20250514 } ] }注意controlUi.gatewayUrl写的是http://gateway:18789这是容器内网络地址。如果你在宿主机浏览器访问 controlUicontrolUi 的 Web 服务会通过这个地址去连 gateway所以必须用服务名而不是 localhost。如果你用的是 Cline MCP 或 Codex 的auth.json方式接入配置逻辑类似核心三件套是 Base URL、Key、Model ID。Cline 的 MCP 配置里baseUrl填https://taotoken.net/apiapiKey填你的 Keymodel填模型 ID。Codex 的auth.json里对应字段是api_base、api_key、model。CC Switch 的场景下你在切换配置时确保这三个字段指向 TaoToken 即可。把文件都建好后执行docker-compose up -d --build第一次构建会拉取 Node 镜像并安装 OpenClaw可能需要几分钟。构建完成后用docker-compose ps确认两个容器都是 Up 状态。4. 验证请求从 gateway 日志到 controlUi 连接成功容器起来之后先别急着开浏览器。按顺序验证 gateway 是否正常监听、模型请求是否能通、controlUi 是否能连上这样出问题时能快速定位是哪一层的问题。第一步看 gateway 日志docker-compose logs -f gateway如果配置正确你会看到类似gateway listening on 0.0.0.0:18789的输出。如果报错EADDRINUSE说明端口被占用改一下 compose 里的端口映射。如果报config file not found检查config/openclaw.json是否挂载到了/root/.openclaw目录下。第二步在容器内测试模型请求。进入 gateway 容器docker exec -it openclaw-gateway sh然后用 curl 发一个请求curl -X POST http://localhost:18789/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer your-gateway-token-here \ -d { model: claude-sonnet-4-20250514, messages: [{role: user, content: 你好请回复ok}] }如果返回的 JSON 里有choices字段和模型回复内容说明 gateway 到 TaoToken 的链路是通的。如果返回 401检查.env里的TAOTOKEN_API_KEY是否正确以及openclaw.json里的apiKey是否和.env一致。如果返回local proxy failed或连接超时检查baseUrl是否写成了https://taotoken.net/api不要多写或少写路径。第三步打开 controlUi。在宿主机浏览器访问http://localhost:3000。页面加载后你会看到一个令牌输入框。把OPENCLAW_GATEWAY_TOKEN的值粘贴进去点击连接。这时候可能会出现设备配对提示。controlUi 会显示一个待批准的设备请求你需要回到容器内执行批准命令。先列出待配对设备docker exec -it openclaw-gateway openclaw devices list输出里会有一个requestId复制它然后执行docker exec -it openclaw-gateway openclaw devices approve 5f2ec3ce-ae5b-4edb-9aa0-68fa5a062df5把5f2ec3ce-ae5b-4edb-9aa0-68fa5a062df5替换成你实际的 requestId。批准成功后gateway 日志里会显示设备已配对的信息。回到 controlUi 页面点击概览中的连接按钮这次应该能正常进入控制台。第四步在 controlUi 里发一条测试消息。如果能看到模型回复说明整条链路——controlUi → gateway → TaoToken → 模型——全部打通。如果 controlUi 显示连接成功但发消息没反应检查 gateway 日志里是否有reading choices相关的报错这通常是模型 ID 写错或 TaoToken 返回格式不匹配导致的。验证模型对话是否正常也可以直接用 TaoToken 的模型对话入口测试确认 Key 本身没问题。如果那边能通问题就在 gateway 配置上。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节整理几个我在部署过程中实际遇到的报错以及对应的排查思路。你遇到问题时可以按这个顺序对照。401 Unauthorized最常见的原因是 Key 写错或没生效。先检查.env里的TAOTOKEN_API_KEY是否以sk-开头有没有多余空格。然后确认openclaw.json里的apiKey和.env一致。如果都没问题进容器执行echo $TAOTOKEN_API_KEY看环境变量是否真的传进去了。有时候 docker-compose 改了.env但没重启容器环境变量不会更新需要docker-compose down docker-compose up -d。local proxy failed这个报错通常出现在 gateway 尝试连接上游 API 时。检查baseUrl是否写成了https://taotoken.net/api注意不要写成https://taotoken.net/api/v1或带其他路径。另外确认容器内能解析和访问外网可以用docker exec -it openclaw-gateway curl -I https://taotoken.net/api测试连通性。如果容器网络有问题检查 docker 的 DNS 配置。reading choices 报错这个一般发生在 gateway 收到上游响应后解析失败。原因可能是模型 ID 写错了TaoToken 返回了错误信息而不是正常的 choices 结构。检查openclaw.json里的modelId是否和控制台里显示的完全一致大小写和连字符都不能错。另外确认请求体里的model字段和配置里的modelId一致。OAuth 相关报错如果你在 controlUi 里看到 OAuth 授权失败的提示通常是因为 gateway 的 token 配置和 controlUi 里输入的不匹配。检查openclaw.json里的gateway.token和.env里的OPENCLAW_GATEWAY_TOKEN是否一致。如果不一致改完后重启 gateway 容器。另外设备配对没批准也会导致 OAuth 流程中断按第 4 节的步骤执行openclaw devices approve即可。controlUi 页面空白或连不上先确认 controlui 容器是否在运行docker-compose ps看状态。如果容器频繁重启看日志docker-compose logs controlui。常见原因是--gateway参数指向的地址不对容器内必须用服务名http://gateway:18789不能用localhost。另外确认 controlui 的端口映射是否正确宿主机访问的是http://localhost:3000。gateway 启动后立即退出检查openclaw.json的 JSON 格式是否合法可以用python -m json.tool config/openclaw.json验证。如果配置文件里有注释或尾随逗号会导致解析失败。另外确认config目录的挂载路径是否正确容器内路径是/root/.openclaw。排查时养成看日志的习惯gateway 和 controlui 的日志分别用docker-compose logs -f gateway和docker-compose logs -f controlui查看。大部分问题在日志里都有明确提示。6. 把模型调用统一走 TaoToken 的长期实践链路跑通之后你可以把 OpenClaw 的模型调用固定走 TaoToken 通道这样后续切换模型或调整额度都在 TaoToken 控制台操作不用改 gateway 配置。具体做法是在openclaw.json的models.default里把provider设为taotokenbaseUrl和apiKey指向 TaoToken。如果以后要换模型只改modelId就行。对于需要长期跑 Agent 或编码任务的场景建议开通 Coding Plan这样在调用频率和并发上更稳定。入口在 TaoToken 控制台的套餐页面按你的实际用量选择。开通后Key 的权限和额度会自动更新gateway 不需要重启就能生效。如果你同时用 Cline、Codex 或 CC Switch可以把它们的 Base URL 都指向https://taotoken.net/apiKey 用同一个Model ID 按各自配置填。这样多个工具共享一个通道管理起来更省心。Cline 的 MCP 配置里注意baseUrl不要带尾部斜杠Codex 的auth.json里api_base字段同理。日常维护上建议把config/openclaw.json和.env纳入版本管理但不要把真实 Key 提交到公开仓库。可以用.env.example放占位符实际.env加到.gitignore。gateway 的日志会滚动写入logs/gateway.log定期清理避免占满磁盘。最后如果你在容器里改了配置记得重启对应容器让配置生效。gateway 改配置后执行docker-compose restart gatewaycontrolui 改配置后执行docker-compose restart controlui。设备配对信息保存在config目录下重启不会丢失不需要重新批准。整套流程跑下来从docker-compose up -d --build到 controlUi 里看到模型回复顺利的话十分钟以内能完成。遇到报错就按第 5 节的顺序排查大部分问题都能定位到具体的配置项。