跳转至

OpenClaw 在 proxy-kr 上的 Portainer 部署

这份记录是已经实际跑通的最终方案。

当前结论:

  • 使用 Portainer Stack 部署
  • 接入 proxy-kr
  • Traefik-KR 反向代理
  • 不额外暴露 ports
  • 只常驻 openclaw-gateway
  • 数据统一放在 /opt/infra/stacks/app-openclaw
  • 不挂 security-ip-whitelist@docker
  • 浏览器首次访问需要 token + pairing

1. 目录准备

在目标服务器上执行:

mkdir -p /opt/infra/stacks/app-openclaw/{config,workspace}
chown -R 1000:1000 /opt/infra/stacks/app-openclaw

2. 生成 OPENCLAW_GATEWAY_TOKEN

优先使用:

openssl rand -hex 32

如果宿主机已安装 openclaw CLI,也可以使用:

openclaw doctor --generate-gateway-token

把生成结果填入 Portainer 的环境变量。

3. Portainer Stack

在 Portainer 中新建 Stack,名称建议为 app-openclaw,内容如下:

services:
  openclaw-gateway:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw-gateway
    restart: unless-stopped
    init: true
    environment:
      HOME: /home/node
      TERM: xterm-256color
      TZ: Asia/Shanghai
      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
    command: ["node", "dist/index.js", "gateway", "--bind", "lan", "--port", "18789", "--allow-unconfigured"]
    volumes:
      - /opt/infra/stacks/app-openclaw/config:/home/node/.openclaw
      - /opt/infra/stacks/app-openclaw/workspace:/home/node/.openclaw/workspace
    networks:
      - proxy-kr
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.openclaw.rule=Host(`openclaw.120224.xyz`)"
      - "traefik.http.routers.openclaw.entrypoints=websecure"
      - "traefik.http.routers.openclaw.tls.certresolver=letsencrypt"
      - "traefik.http.services.openclaw.loadbalancer.server.port=18789"

networks:
  proxy-kr:
    external: true

4. Portainer 环境变量

在 Stack 的 Environment variables 中添加:

OPENCLAW_GATEWAY_TOKEN=<生成的 token>

5. 首次初始化

部署完成后,在 Portainer 中进入 openclaw-gateway 容器控制台执行:

node dist/index.js onboard --mode local --no-install-daemon

初始化过程中按下面选择:

  • I understand this is personal-by-default... Continue?Yes
  • QuickStart / ManualManual
  • Gateway modelocal
  • Bind/networklan
  • Port18789
  • Tailscale 跳过或关闭
  • Auth / shared mode 保持个人使用默认,不开启多用户共享
  • Configure DM access policies now? (default: pairing) 可以直接按回车,使用默认 pairing

初始化完成后继续执行:

node dist/index.js config set gateway.bind lan
node dist/index.js config set gateway.controlUi.allowedOrigins '["https://openclaw.120224.xyz"]' --strict-json

改完后重启 openclaw-gateway 容器或重新部署 Stack。

6. 首次访问

首次访问建议使用:

https://openclaw.120224.xyz/?token=<OPENCLAW_GATEWAY_TOKEN>

如果配置正确,页面会进入网关仪表盘。

7. Pairing required

如果页面提示:

pairing required

说明当前浏览器还没有被批准,这是正常现象。

openclaw-gateway 容器中执行:

node dist/index.js devices list

找到新的 Pending 设备后执行:

node dist/index.js devices approve <requestId>

批准后刷新浏览器即可进入。

8. 这次实际踩过的坑

不要部署 openclaw-cli

openclaw-cli 不是常驻服务。把它放进 Stack 后会因为进程退出而持续 Restarting

gateway 需要 --allow-unconfigured

在配置目录还是空的时候,如果不带这个参数,openclaw-gateway 可能直接启动失败并不断重启。

不要给 OpenClaw 主入口挂 security-ip-whitelist@docker

这会导致浏览器访问和后续外部平台回调更容易被拦住。当前实际跑通的版本没有挂这个中间件。

allowedOrigins 要写浏览器实际访问地址

当前应设置为:

https://openclaw.120224.xyz

不是容器内部地址,也不是 127.0.0.1:18789

9. 最终确认项

跑通后的关键状态应该是:

  • openclaw-gateway 容器为 running
  • 浏览器访问 https://openclaw.120224.xyz/?token=... 能进入网关页面
  • 首次显示 pairing required 后,批准设备即可正常使用