1. Docker 部署 OpenClaw 后 Web UI 打不开的真实场景
Docker 部署 OpenClaw 这件事,看起来就是把镜像拉下来、容器跑起来,但真正卡人的地方往往在容器启动之后。我见过太多人在终端里看到容器状态是 Up,日志也没有明显报错,结果浏览器一打开http://127.0.0.1:18789直接连接被重置,换成局域网 IP192.168.5.30:18789还是无法访问。这时候大多数人第一反应是防火墙、代理、端口映射,挨个排查一圈,最后发现根因跟这些都没关系。
OpenClaw 的 Web UI 访问问题,核心在于它的网关层有一套跨域访问控制机制。你可以把它理解成小区门禁:容器确实在跑,端口也确实映射出来了,但网关只允许「从特定地址打开的网页」来连接它并下发控制指令。如果你的访问来源不在白名单里,网关会直接拒绝,表现就是连接被重置或者无法访问。这个机制默认比较严格,尤其在 Docker 环境下,容器内外网络视图不一致,很容易触发。
除了 Web UI,飞书配对和自定义模型配置也是高频卡点。飞书这边,机器人发消息没反应、系统提示未配对、配对码还一直变,很多人不知道去哪里拿正确的配对码。自定义模型配置则是另一个坑,公司自建的大模型节点要接进来,Base URL、API Key、模型 ID 三样东西填错一个就调不通,而且报错信息往往不直观。
这篇内容聚焦 Docker 环境下 OpenClaw 的完整落地流程,覆盖 Web UI 无法访问、飞书配对失败、自定义模型接入这三类问题。我会给出可复制的 docker-compose 配置、端口与反向代理排查清单、飞书应用凭证填写位置,以及自定义模型 Base URL 与 Key 的配置示例,每一步都附上验证动作。如果你正在用 Docker 跑 OpenClaw,或者准备把公司自建模型节点接进来,这篇可以帮你少走几个小时的弯路。
2. TaoToken 前置准备:模型接入的 Base URL 与 Key 怎么拿
在讲 OpenClaw 的模型配置之前,先把模型接入这一层说清楚。OpenClaw 本身是一个 Agent 框架,它需要调用一个大模型来完成对话和任务。你可以用公司自建节点,也可以用兼容 OpenAI 接口的模型服务。不管用哪种,你都需要三样东西:Base URL、API Key、Model ID。这三样缺一不可,而且格式必须对。
如果你手头没有现成的模型节点,或者想先用一个稳定的兼容接口把 OpenClaw 跑通,可以走 TaoToken 这条路径。它的接口格式兼容 OpenAI 的openai-completions,正好是 OpenClaw 配置里推荐用的 API 格式。你需要先去官网注册并拿到 API Key,地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。注册完成后,在控制台里创建 API Key,这个 Key 就是后面填到apiKey字段里的值。
拿到 Key 之后,Base URL 用 https://taotoken.net/api ,注意这个地址后面不加 UTM 参数,直接作为baseUrl填进去。Model ID 则根据你在控制台里选择的模型来填,比如MiniMax-M2.7-highspeed这类名称。这里要提醒一句,Base URL 和 Model ID 必须匹配,不能拿 A 服务的地址去调 B 服务的模型,否则会报模型不存在的错误。
如果你用的是公司自建节点,逻辑是一样的:找运维或平台负责人要 Base URL、API Key 和 Model ID。自建节点通常会把 API 格式做成 OpenAI 兼容,这样 OpenClaw 配置起来最省事。如果自建节点用的是其他格式,比如 Anthropic 原生格式,那配置字段会不一样,需要单独处理。这篇主要讲openai-completions这种兼容性最好的方式。
还有一个容易忽略的点:API Key 的权限。有些平台的 Key 是分权限的,只能调特定模型,或者有 IP 白名单限制。你在本地 Docker 环境里调试时,如果 Key 绑定了固定 IP,而容器出口 IP 和宿主机不一致,也会导致 401。所以拿到 Key 之后,先确认它的调用范围,再往 OpenClaw 里填。
把这三样东西准备好,后面的配置就是填空题。我建议你先把 Base URL、API Key、Model ID 写在一个临时文本里,确认没有多余空格和换行,再往 JSON 里粘贴。很多配置失败不是逻辑问题,而是复制粘贴时带进了不可见字符。
3. 可复制配置:docker-compose 与 openclaw.json 完整片段
这一节直接给可复制的配置。先看 docker-compose 部分。OpenClaw 的容器需要把配置目录挂载出来,这样你改openclaw.json之后重启容器就能生效,不用重新构建镜像。下面是一个可用的 docker-compose 片段,端口映射和卷挂载都写清楚了。
services: openclaw: image: openclaw/openclaw:latest container_name: openclaw restart: unless-stopped ports: - "18789:18789" volumes: - ~/.openclaw:/root/.openclaw environment: - TZ=Asia/Shanghai command: ["openclaw", "gateway", "--config", "/root/.openclaw/openclaw.json"] openclaw-cli: image: openclaw/openclaw:latest container_name: openclaw-cli profiles: ["cli"] volumes: - ~/.openclaw:/root/.openclaw entrypoint: ["openclaw"]这里有两个服务:openclaw是常驻的网关服务,openclaw-cli是用来执行一次性命令的,比如飞书配对审批。openclaw-cli用了profiles: ["cli"],默认不启动,需要的时候用docker compose run --rm openclaw-cli来跑。卷挂载把宿主机的~/.openclaw映射到容器内的/root/.openclaw,这样配置文件在宿主机上改,容器里能直接读到。
接下来是~/.openclaw/openclaw.json的核心配置。这个文件分几块:gateway 控制网关和 Web UI 访问,agents 控制默认模型,models 控制模型提供方。下面是一个完整示例,把 Web UI 白名单、自定义模型节点都写进去了。
{ "gateway": { "port": 18789, "mode": "local", "bind": "lan", "controlUi": { "allowedOrigins": ["*"], "dangerouslyDisableDeviceAuth": true } }, "agents": { "defaults": { "model": "taotoken/MiniMax-M2.7-highspeed" } }, "models": { "mode": "merge", "providers": { "taotoken": { "api": "openai-completions", "baseUrl": "https://taotoken.net/api", "apiKey": "你的APIKey", "models": [ { "id": "MiniMax-M2.7-highspeed", "name": "MiniMax2.7highspeed" } ] } } } }配置解析一下。gateway.controlUi.allowedOrigins里填["*"]是通配符,表示允许所有来源访问 Web UI。这在本地调试阶段最省事,但如果你要把服务暴露到公网,建议改成具体的域名或 IP,比如["http://192.168.5.30:18789"]。dangerouslyDisableDeviceAuth设为 true 是关闭设备认证,同样只建议在受信任的内网环境用。
agents.defaults.model里的值格式是提供方名称/模型ID,这里写的是taotoken/MiniMax-M2.7-highspeed,对应下面models.providers.taotoken里声明的节点。models.mode设为merge表示合并模式,你可以在 providers 下声明多个节点,OpenClaw 会把它们合并到可用模型列表里。
models.providers.taotoken里的api字段固定写openai-completions,这是兼容性最好的格式。baseUrl填 https://taotoken.net/api ,apiKey填你从控制台拿到的 Key。models数组里声明这个节点下有哪些模型可用,id是调用时用的标识,name是显示名称。
如果你用的是公司自建节点,把taotoken换成公司节点名称,baseUrl和apiKey换成公司提供的值,models数组里的id换成公司节点的模型 ID 就行。结构完全一样,不用改其他字段。
改完配置后,重启容器让配置生效:
docker compose down docker compose up -d openclaw docker compose logs -f openclaw日志里看到网关启动成功、端口监听在 18789,就说明配置被正确加载了。如果日志里报 JSON 解析错误,多半是配置文件里有语法问题,比如多了逗号、少了引号,可以用python -m json.tool ~/.openclaw/openclaw.json来校验。
4. 验证请求:Web UI 访问、飞书配对与模型调用逐步验证
配置写完之后,不能只看容器状态,要逐步验证三个环节:Web UI 能不能打开、飞书配对能不能通过、模型能不能正常调用。这一节给具体的验证动作和预期结果。
先验证 Web UI。在浏览器里打开http://127.0.0.1:18789,如果之前遇到连接被重置,改完allowedOrigins之后应该能正常打开控制台页面。如果还是打不开,换局域网 IP 试,比如http://192.168.5.30:18789。两个地址都试一遍,因为bind设为lan时,容器会监听所有网络接口,但宿主机防火墙可能只放行了部分来源。
验证的时候可以同时看容器日志:
docker compose logs -f openclaw | grep -i "origin\|cors\|control"如果日志里出现 origin 被拒绝的记录,说明allowedOrigins没生效,检查一下配置文件路径是不是挂载对了,以及容器有没有重启。有时候改了宿主机文件但没重启容器,配置不会热加载。
Web UI 能打开之后,验证飞书配对。飞书这边的问题是配对码一直变,因为每次发消息都会生成新的配对请求。正确的做法是不要反复发消息,而是通过 CLI 查看最新的配对请求,然后手动审批。
先查看当前配对列表:
docker compose run --rm openclaw-cli pairing list feishu输出会是一个表格,里面有配对码、发送者 ID、时间戳。找到最新的一条,记下配对码,比如ZLX3M556。然后执行审批:
docker compose run --rm openclaw-cli pairing approve feishu ZLX3M556日志输出Approved feishu sender ou_...就表示授权成功。这时候再在飞书里给机器人发消息,应该能收到回复了。如果审批时报配对码不存在,说明你拿到的码已经过期,重新跑一次pairing list feishu拿最新的。
飞书应用凭证的填写位置在openclaw.json的 channels 节点下,需要填 App ID 和 App Secret。这两个值从飞书开放平台的应用管理后台拿。填完之后重启容器,再用pairing list feishu确认通道状态是 connected。
最后验证模型调用。最直接的方式是在 Web UI 里发一条消息,看有没有回复。如果回复正常,说明模型配置生效了。如果报错,看容器日志里的具体错误信息。常见的错误有 401、模型不存在、连接超时。
也可以用 CLI 直接测试模型:
docker compose run --rm openclaw-cli agent run --message "你好,测试一下模型"如果返回正常的文本回复,说明agents.defaults.model指向的模型节点工作正常。如果报model not found,检查agents.defaults.model里的提供方名称和模型 ID 是否和models.providers里声明的一致。如果报 401,检查apiKey是否正确、有没有多余空格。
三个环节都验证通过后,整个部署就算跑通了。建议把验证命令记下来,以后换环境或者改配置时可以快速回归测试。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
这一节对照真实报错来排查。OpenClaw 在 Docker 环境下常见的错误就那么几类,每一类都有明确的排查方向。
401 Unauthorized。这个错误出现在模型调用环节,说明 API Key 无效或者权限不够。先检查openclaw.json里apiKey字段的值,确认没有多余空格、没有换行、没有把 Key 截断。然后确认这个 Key 在对应平台上是否有效,有没有过期。如果用的是 TaoToken 的 Key,去控制台确认 Key 状态是启用。如果 Key 绑定了 IP 白名单,确认容器出口 IP 在白名单里。Docker 默认用 bridge 网络,出口 IP 是宿主机 IP,但如果你改了网络模式,出口 IP 可能不一样。
local proxy failed。这个错误通常出现在容器启动阶段,说明 OpenClaw 尝试连接本地代理但失败了。检查 docker-compose 里有没有设置HTTP_PROXY或HTTPS_PROXY环境变量,如果有,确认代理地址在容器内可达。如果不需要代理,把这些环境变量删掉。另外检查openclaw.json里有没有配置 proxy 相关字段,不需要的话也删掉。
reading choices 报错。这个错误出现在模型返回解析阶段,说明 OpenClaw 收到了响应,但响应格式不符合预期。常见原因是api字段填错了,比如填成了anthropic但实际节点是 OpenAI 兼容格式。确认api字段是openai-completions。另一个原因是模型返回了非标准格式,比如流式响应被截断。可以先用 CLI 直接调模型,看原始返回是什么样。
OAuth 相关错误。如果配置里用了需要 OAuth 认证的模型服务,但没完成授权流程,会报 OAuth 错误。OpenClaw 支持 OAuth 的设备码流程,需要先在 CLI 里执行授权命令,拿到 token 后再配置。如果用的是 API Key 方式,就不需要 OAuth,确认配置里没有混用两种认证方式。
除了这些具体报错,还有几个通用排查动作。第一,确认配置文件路径正确,宿主机~/.openclaw/openclaw.json映射到容器内/root/.openclaw/openclaw.json。第二,确认容器重启过,配置改动不会热加载。第三,确认端口没有被占用,docker compose ps看端口映射状态。第四,确认防火墙放行了 18789 端口,尤其是局域网访问场景。
如果用了 CC Switch、Cline MCP 或者 Codex 的 auth.json,配置里必须写全三件套:Base URL、Key、Model ID。缺任何一个都会导致调用失败。Base URL 用 https://taotoken.net/api ,Key 用控制台拿到的值,Model ID 用模型列表里的标识。三样东西的格式和位置都要对,不能只填其中两个。
排查的时候建议按顺序来:先看容器日志,再看配置文件,最后看网络连通性。日志里通常有最直接的错误信息,配置文件问题用 JSON 校验工具查,网络问题用curl在容器内测试。
6. 语义一致 CTA:把 OpenClaw 接入流程走完整
OpenClaw 在 Docker 里跑通之后,模型接入这一层建议用兼容 OpenAI 格式的接口,配置最简单,出错也容易排查。如果你还没有可用的模型节点,可以走 TaoToken 这条路径,Base URL 用 https://taotoken.net/api ,Key 在控制台创建,Model ID 按需选择。配置片段直接套用第 3 节的 JSON,把taotoken换成你的节点名称就行。
接入过程中如果遇到 401 或者模型不存在的报错,优先检查 Key 和 Model ID 是否匹配。需要看具体接口文档的话,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有 Base URL 和参数说明。想先验证模型对话效果,可以在 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 里直接试。如果打算长期跑编码类 Agent 任务,Coding Plan 在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ,API Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。
飞书配对那边,记住不要反复发消息,用pairing list feishu拿最新配对码,再用pairing approve feishu审批。Web UI 访问问题,先改allowedOrigins,再重启容器,最后用局域网 IP 和本地 IP 各试一次。这三步走完,Docker 部署 OpenClaw 的完整流程就闭环了。