1. 为什么 OPENCLAW_GATEWAY_TOKEN 总是配不对如果你正在用 Docker Compose 跑 OpenClaw 网关多半踩过这个坑.env里明明写了OPENCLAW_GATEWAY_TOKENdocker compose config也能看到变量被注入但打开控制面板还是弹 401或者日志里反复提示Channel enabled but token not set。问题通常不在 Token 本身而在三个东西的配合关系上——OPENCLAW_GATEWAY_TOKEN这个环境变量、env_file的加载时机、以及gateway.auth.mode到底有没有被设成token。OpenClaw 网关是一个自托管的 AI 助手接入层负责把消息通道、模型调用、控制面板统一收口到一个端口默认 18789。OPENCLAW_GATEWAY_TOKEN就是这层网关的共享密钥当gateway.auth.modetoken时所有访问控制面板和 API 的请求都要带上它。它适合谁适合想把 AI 助手跑在自己服务器或本地 Docker 环境、又不想把网关裸奔暴露的人。这篇就聚焦 Docker Compose 场景把 env_file 与 gateway.auth.mode 的配合方式讲透给你可复制的 compose 片段、.env骨架以及用 openssl 生成令牌后的一次完整启动验证。我试过最典型的翻车方式.env文件放在项目根目录docker-compose.yml放在deploy/子目录结果env_file: - .env相对路径找不到文件Compose 静默跳过容器里根本没有这个变量。所以第一步不是写 Token而是搞清楚变量从哪来、到哪去。2. 前置准备TaoToken 与 OpenClaw 网关的关系在动手配 Token 之前先把模型侧和网关侧分清楚。OpenClaw 网关管的是「谁能访问我的助手」而模型调用管的是「助手用什么模型回答」。这两件事的凭据是分开的网关用OPENCLAW_GATEWAY_TOKEN模型侧则走 API Key。如果你还没准备模型侧的 Key可以先去 TaoToken 控制台创建一个。地址是 https://taotoken.net/api-keys 注册后在控制台里生成 API Key复制出来备用。这个 Key 后面会写进 OpenClaw 的模型配置里和网关 Token 是两个独立的东西别混用。TaoToken 的接入文档在 https://taotoken.net/doc 里面有模型列表和 base_url 的说明。OpenClaw 网关本身不绑定特定模型供应商你只要在配置里填对 base_url 和 api_key 就能接上。想先验证模型通不通可以用模型对话页面 https://taotoken.net/models 直接发一条消息测试确认 Key 有效再往网关里塞能省掉一半排障时间。如果你打算长期跑编码类 Agent或者让 OpenClaw 网关承接日常的 coding 任务可以看下 Coding Plan https://taotoken.net/coding-plan 它针对高频调用场景做了额度规划比按量付费更可控。这一步不是必须的但先把模型侧理顺后面网关鉴权出问题时你就能确定「不是模型 Key 的锅」。3. 可复制配置compose 片段与 .env 骨架3.1 用 openssl 生成强随机 Token别手敲密码也别用123456。在终端执行openssl rand -hex 32输出是一串 64 位十六进制字符例如e0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1这就是你的OPENCLAW_GATEWAY_TOKEN。把它存好后面.env和客户端都要用同一个值。注意openssl rand -hex 32生成的是 32 字节即 64 个十六进制字符强度足够如果你想要更短-hex 16也行但不建议低于 32 位。3.2 .env 文件骨架在docker-compose.yml同目录下创建.env# .env OPENCLAW_GATEWAY_TOKENe0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1 OPENCLAW_AUTH_MODEtoken这里我多加了一个OPENCLAW_AUTH_MODE原因在下一节讲。.env文件务必加进.gitignoreecho .env .gitignore3.3 docker-compose.yml 片段services: openclaw: image: your-openclaw-image:latest container_name: openclaw-gateway restart: unless-stopped ports: - 127.0.0.1:18789:18789 env_file: - .env environment: - OPENCLAW_GATEWAY_TOKEN${OPENCLAW_GATEWAY_TOKEN} - OPENCLAW_AUTH_MODE${OPENCLAW_AUTH_MODE} volumes: - ./data:/app/data - ./config:/app/config关键点有三个。第一env_file的路径是相对于 compose 文件所在目录的不是相对于你执行命令的目录所以.env和docker-compose.yml放一起最省事。第二environment里显式引用${OPENCLAW_GATEWAY_TOKEN}这是从宿主机 shell 环境或.env插值进来的和env_file是两条不同的注入路径两者都写能避免「变量到底进没进容器」的扯皮。第三端口映射写成127.0.0.1:18789:18789只绑本地回环公网访问不到这是最省心的安全默认值。3.4 gateway.auth.mode 到底怎么设这是最容易漏的一环。OPENCLAW_GATEWAY_TOKEN只是「钥匙」gateway.auth.mode才是「锁有没有装上」。如果 auth mode 不是token你配了 Token 也不会生效网关会以无鉴权模式运行。在 OpenClaw 的配置文件通常是config/gateway.yaml或config/config.yaml里要有这样一段gateway: auth: mode: token token: ${OPENCLAW_GATEWAY_TOKEN}注意token字段引用的是环境变量。OpenClaw 的配置加载顺序里环境变量会覆盖配置文件中的同名设置所以即使配置文件里写死了 tokenOPENCLAW_GATEWAY_TOKEN也会把它顶掉。这就是为什么前面.env里那个变量必须和配置文件里的引用名一致。如果你不想改配置文件也可以用环境变量直接控制 auth mode。部分版本支持OPENCLAW_AUTH_MODE这个变量但不同版本行为不一致最稳的做法还是显式在配置文件里写mode: token然后用环境变量提供 token 值。4. 启动验证确认鉴权模式真的生效4.1 启动并检查变量注入docker compose up -d docker compose exec openclaw env | grep OPENCLAW你应该看到OPENCLAW_GATEWAY_TOKENe0e1f2a3... OPENCLAW_AUTH_MODEtoken如果grep没有任何输出说明变量没进容器。回到第 3 节检查env_file路径和environment引用。如果变量在但值是空的检查.env里有没有多余空格或引号。4.2 验证鉴权模式docker compose exec openclaw openclaw config get gateway.auth.mode期望输出token如果输出是none或空说明配置文件没生效或者被别的配置覆盖了。这时候检查config/目录有没有被正确挂载以及配置文件里的缩进是不是 YAML 合法。4.3 用 curl 验证 Token 鉴权不带 Token 请求控制面板curl -i http://127.0.0.1:18789/期望返回401 Unauthorized。如果返回 200说明鉴权没生效auth mode 没设对。带上 Token 请求curl -i -H Authorization: Bearer e0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1 http://127.0.0.1:18789/期望返回 200 或控制面板的 HTML。如果还是 401检查 Token 值是否和.env里完全一致注意别把换行符带进去。4.4 浏览器访问控制面板打开http://127.0.0.1:18789首次访问会要求输入 Token。粘贴.env里的值认证通过后就能进控制面板。如果浏览器缓存了旧 Token 导致 401清一下站点数据再试。5. 本篇常见错排查5.1 401 Unauthorized 但 Token 明明是对的最常见的原因是客户端和服务端的 Token 不一致。重启容器后如果 Token 变了比如你重新生成了客户端配置没同步更新就会 401。用docker compose exec openclaw env | grep OPENCLAW_GATEWAY_TOKEN核对容器内实际生效值再和客户端配置比对。另一个原因是请求头格式不对。OpenClaw 网关期望的是Authorization: Bearer token不是X-Auth-Token或裸 token。用 curl 测试时把 header 写全。5.2 日志提示 Channel enabled but token not set这个报错和网关 Token 不是一回事。它说的是某个消息通道比如 Telegram、Discord 通道启用了但没配该通道自己的 Token。解决方式二选一要么在配置文件里给该通道补上 Token要么把该通道的enabled设为false。别把通道 Token 和网关 Token 搞混。5.3 env_file 不生效三个检查点.env是否和docker-compose.yml同目录env_file缩进是否正确YAML 对缩进敏感变量名有没有拼错。可以用docker compose config查看 Compose 解析后的最终配置如果environment段里变量值是空的说明插值没成功。5.4 公网部署的安全红线如果你把端口映射改成0.0.0.0:18789:18789等于把网关暴露到公网。OPENCLAW_GATEWAY_TOKEN是完整操作权限凭证泄露它等同于交出服务器控制权。公网部署前务必读官方 Security Hardening Guide配好防火墙规则只放行必要来源 IP。更稳的做法是保持127.0.0.1绑定通过 SSH 隧道或反向代理加额外认证层访问。5.5 变量优先级冲突OpenClaw 的配置优先级是环境变量 配置文件。如果你在配置文件里写死了 token又在.env里写了不同的值最终生效的是.env的值。排查时用openclaw config get gateway.token看当前生效值别只看配置文件。6. 把 Token 管好网关才稳配 OpenClaw 网关的 Token核心就三件事用openssl rand -hex 32生成强随机值用.envenv_file隔离配置用gateway.auth.mode: token把锁装上。三者缺一个鉴权就会以你意想不到的方式失效。日常维护上.env永远不进 GitToken 定期轮换轮换后记得同步更新所有客户端。如果你还在调模型侧的接入API Key 在 https://taotoken.net/api-keys 管理接入文档在 https://taotoken.net/doc 模型验证用 https://taotoken.net/models 。长期跑编码 Agent 的话Coding Plan https://taotoken.net/coding-plan 能把额度规划得更清楚。网关鉴权排障优先看 API Keys 和接入文档模型通不通先过模型对话别把两类问题混在一起查。