
1. 为什么要把 OpenClaw 塞进 Docker 再套一层 OpenRestyOpenClaw 这类带网关、带工具调用、还要跑浏览器自动化的服务直接裸装在宿主机上最头疼的不是装不上而是装完之后环境互相污染。它要 Chromium、要 Playwright、要 systemd、要自己的 Docker 守护进程宿主机上但凡有点别的服务端口、内核模块、依赖版本就开始打架。OpenClaw-In-Docker 这个开源项目GitHub 上 cncfstack/openclaw-in-docker解决的正是这件事把整套东西封进一个类虚拟机的隔离容器里容器内自带 systemd、自带独立 Docker、自带 OpenResty对外只暴露 80 和 443。但真正让它在公网可用还差两块拼图。第一块是 HTTPS项目默认用 OpenSSL 自签证书浏览器会拦网关的allowedOrigins也容易对不上第二块是 OpenResty 反向代理它不只是转发还承担了基于 Lua 的登录认证——用户必须先过登录页才能摸到 OpenClaw 的原生页面。这两块配好OpenClaw 才算真正“安全、独立、便捷”地跑起来。而多服务场景下还有个隐性痛点OpenClaw 网关要 TokenTaoToken 侧要 API Key如果每个服务各存一份密钥轮换和审计就是灾难。这篇就按“Docker 部署 → OpenResty 反代 HTTPS → TaoToken 统一 Key 接入 → curl 验证”的顺序走一遍命令和配置都能直接抄。适合谁看手里有一台能跑 Docker 的机器、想把 OpenClaw 放到公网但不想裸奔、同时希望把模型调用的 Key 收敛到一处的开发者。下面所有操作我都按可复制的粒度写遇到坑的地方会标出来。2. TaoToken 前置准备统一 Key 与接入信息在动 Docker 之前先把 TaoToken 这侧的接入信息准备好不然后面 OpenClaw 网关连上了、模型却调不通排查会绕远路。TaoToken 在这里扮演的角色是统一的模型调用入口OpenClaw 内部要调模型时不再各自散落 Key而是走同一个 Base URL 同一个 Key模型 ID 按需切换。你需要拿到三样东西我把它叫“三件套”后面所有配置都围绕它项目值说明Base URLhttps://taotoken.net/api所有请求的根地址注意不要带多余路径API Key控制台生成形如sk-开头的一串只显示一次及时保存Model ID按需选择例如对话类、编码类模型填进请求体的model字段获取路径很直接打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 进控制台在 API Keys 页面新建一个 Key。建议按用途命名比如openclaw-gateway这样以后要吊销或轮换时一眼能认出来。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 页面是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。这里有个容易忽略的点OpenClaw 网关本身用的是 WebSocket 令牌wss://那套和 TaoToken 的 API Key 是两码事。网关令牌管的是“浏览器能不能连上 OpenClaw 网关”TaoToken Key 管的是“OpenClaw 调模型时能不能通过鉴权”。两者不要混。我见过有人把网关 Token 填进模型配置里结果一直 401查了半天。如果你后面还要接 Claude Code 这类编码工具或者用 Coding Plan 做长期编码任务Key 的规划可以提前想清楚一个 Key 对应一类用途方便在控制台看用量。Coding Plan 的入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 模型对话调试入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到参数不确定时以文档为准。准备好三件套后先别急着配 OpenClaw用一条 curl 确认 Key 本身是通的这一步能省掉后面大量“到底是网络问题还是 Key 问题”的纠结。命令在第四节给。3. 可复制配置docker-compose 与 OpenResty 反代片段原项目给的是docker run长命令能跑但参数一多就难维护尤其是要挂证书、要改环境变量的时候。我把它整理成docker-compose.yml同时把 OpenResty 反代和 HTTPS 证书的挂载路径写清楚。注意容器内已经内置了 OpenResty所以反代配置是改容器内 OpenResty 的站点配置而不是在宿主机再起一个 Nginx。先建目录结构证书和配置都放进去mkdir -p ./data/openclaw01/ssl mkdir -p ./data/openclaw01/openrestydocker-compose.yml如下路径和原项目保持一致只做了编排化services: openclaw: image: registry.cncfstack.com/cncfstack/openclaw-in-docker:v2026.3.11-v0.1.0 container_name: openclaw-in-docker hostname: openclaw-in-docker privileged: true restart: always ports: - 80:80 - 443:443 volumes: - /lib/modules:/lib/modules:ro - openclaw-storage:/var - ./data/openclaw01:/root/.openclaw - ./data/openclaw01/ssl:/etc/openresty/ssl environment: - OPENCLAW_WEB_URLhttps://your.domain.com - OPENCLAW_USERopenclaw - OPENCLAW_PASSWORD换成你的强密码 volumes: openclaw-storage:几个参数必须说清楚不然容易踩坑。privileged: true是因为容器内还要跑 Docker需要挂载内核路径项目也在逐步收缩这个权限但目前还得留着。openclaw-storage:/var是命名卷不是目录挂载别写成./var否则容器内 Docker 会出问题。OPENCLAW_WEB_URL一定要和你实际访问的域名一致它同时决定登录地址、证书生成和allowedOrigins写成localhost却用域名访问网关会拒绝连接。HTTPS 证书部分把合法证书放到./data/openclaw01/ssl/并固定命名为cert.pem和cert.key。如果之前已经生成过自签证书先清掉再放rm -f ./data/openclaw01/ssl/* cp /path/to/fullchain.pem ./data/openclaw01/ssl/cert.pem cp /path/to/privkey.pem ./data/openclaw01/ssl/cert.keyOpenResty 反代配置容器内站点配置一般放在/etc/openresty/conf.d/或项目约定的路径。核心是把 443 的 server 块指向 OpenClaw 上游并保留 Lua 登录认证。下面是一个可参考的 server 片段重点是proxy_pass指向本机 OpenClaw 端口、WebSocket 升级头要带上server { listen 443 ssl; server_name your.domain.com; ssl_certificate /etc/openresty/ssl/cert.pem; ssl_certificate_key /etc/openresty/ssl/cert.key; location / { access_by_lua_block { -- 这里保留项目自带的登录校验逻辑 } proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }Upgrade和Connection这两行是 WebSocket 能不能连上的关键网关走的是wss://少了这两行页面能打开但网关一直转圈。改完配置重启容器docker compose down docker compose up -d docker restart openclaw-in-docker如果你用的是 Cline MCP 或 Codex 的auth.json这类工具配置思路一样都是 Base URL Key Model ID 三件套只是文件位置不同。Claude Code 的接入同理Base URL 填https://taotoken.net/apiKey 填控制台生成的Model ID 按文档选。ClaudeCodeAnthropic 相关说明在 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecode-anthropicutm_campaignrewrite 。4. 验证请求curl 打通接口与网关连接配置写完不验证等于没配。分两步验先验 TaoToken 的 Key 通不通再验 OpenClaw 网关连不连得上。第一步用 curl 打 TaoToken 的接口。这一步和 OpenClaw 无关纯粹确认三件套正确curl -sS https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: 你的模型ID, messages: [{role: user, content: ping}] }把$TAOTOKEN_API_KEY换成你的 Keymodel换成实际模型 ID。返回里能看到choices数组就说明 Key 和 Base URL 都对。如果返回 401先查 Key 有没有复制全、有没有多余空格如果返回模型不存在查 Model ID 拼写。第二步验 OpenClaw 网关。先拿网关令牌cat ./data/openclaw01/openclaw.json | grep token | grep -v mode输出类似token: f64687a164a25e500000000c658b3e488660001dc600c273。然后在浏览器打开https://your.domain.com用OPENCLAW_USER和OPENCLAW_PASSWORD登录进入网关页面WebSocket URL 填wss://your.domain.comToken 填上面拿到的值点连接。新设备第一次连会触发审批。推荐用提示里的命令审批或者手动跑docker exec -i openclaw-in-docker bash -- /usr/local/bin/openclaw-autoapprove-devices.sh审批后等 30 秒或刷新页面。这一步的坑在于审批脚本会放行所有设备所以务必确认你的 OpenClaw 只对可信的人开放别把登录密码设成默认的openclaw。再补一条容器内验证确认 OpenClaw 服务本身活着docker exec -it openclaw-in-docker /bin/bash openclaw --version能进到 Debian 环境、/app是源码目录、/root/.openclaw/是配置目录说明容器结构正常。到这里HTTPS、反代、网关、模型 Key 四条链路都通了。5. 本篇常见错排查401、local proxy failed 与证书不匹配配这套东西报错基本集中在几个固定位置。我把真实遇到过的对照着写方便你直接定位。401 Unauthorized。两种可能一是 TaoToken Key 错二是网关 Token 错。区分方法很简单用第四节第一条 curl 单独测 Key通了就说明是网关 Token 问题。网关 Token 从openclaw.json里取注意别把mode字段的值也 grep 进去所以命令里带了grep -v mode。另外 Key 前后有换行或空格也会 401复制时留意。local proxy failed。这个多半出在 OpenResty 反代或 WebSocket 升级头上。检查proxy_set_header Upgrade和Connection upgrade两行在不在proxy_pass指向的端口对不对。还有一种情况是OPENCLAW_WEB_URL和实际访问域名不一致导致allowedOrigins校验失败表现也是连接被拒。改完环境变量必须重启容器光改 compose 文件不重启不生效。reading choices 报错。这通常是模型返回体解析问题根源在请求参数。检查model字段是不是有效 ID、messages结构对不对、Content-Type有没有带。如果用的是流式注意客户端要按 SSE 解析别当普通 JSON 读。OAuth 相关报错。如果你接的是 Claude Code 这类走 OAuth 的工具报错往往出在回调地址或 token 交换环节。确认 Base URL 用的是https://taotoken.net/api不要多加/v1之外的路径。ClaudeCodeAnthropic 的接入细节以文档为准别凭记忆填。证书不匹配 / NET::ERR_CERT。自签证书必然报这个要么换合法证书要么在测试环境手动信任。换证书时记得先rm -f ./data/openclaw01/ssl/*再放新证书文件名必须是cert.pem和cert.key名字错了 OpenResty 起不来。重启后如果还报旧证书检查是不是浏览器缓存换个无痕窗口试。容器起不来 / Docker 内 Docker 异常。先看openclaw-storage这个命名卷在不在别误删。privileged没开、/lib/modules没挂容器内 Docker 会直接失败。升级版本时用新镜像 tag 重新docker compose up -d即可数据在挂载目录和命名卷里不会丢。排查顺序建议固定成先 curl 验 Key → 再验网关 Token → 再看反代头 → 最后看证书。按这个顺序走基本不会绕圈。6. 把 Key 收敛到一处之后整套跑下来最省心的其实不是 Docker 那层隔离而是 Key 不再散落。OpenClaw 网关令牌管访问TaoToken Key 管模型调用各司其职轮换时只动一个地方。证书和反代配好之后OpenClaw 就能以一个相对干净的姿态挂在公网容器内那套独立 Docker 也不会污染宿主机。后续如果要扩比如再加一个编码 Agent 或换模型直接复用同一个 Base URL 和 Key只改 Model ID 就行。需要长期跑编码任务的可以看 Coding Plan只是临时验证模型的用模型对话页面更快。接入过程中卡在参数上的翻接入文档比搜帖子靠谱。