目录

使用 Docker 部署 OpenClaw

上一篇介绍了通过 NPM 安装 OpenClaw 并配置 qqbot。本文介绍在 VPS 上使用 Docker 部署 OpenClaw 的完整流程,适用于需要长期运行、资源隔离的生产环境。

为什么要用 Docker

相比 NPM 直接安装,Docker 部署有这些优势:

  • 环境一致:容器内环境固定,不会受宿主机 Node 版本影响
  • 资源隔离:方便限制 CPU/内存,避免影响其他服务
  • 易于管理:通过 docker compose 一键启停、查看日志
  • 安全:容器内运行权限受限,减少攻击面

如果你的 VPS 已经运行 Docker,推荐使用本方案。

准备配置文件目录

首先在服务器上创建配置目录,建议放在主目录下的 .openclaw 目录,比如 /home/gitop/.openclaw

mkdir -p /home/gitop/.openclaw/workspace

后面所有容器内的配置文件(openclaw.json 等)都会持久化到这个目录,即使容器删除也不会丢失。

编写 docker-compose.yml

在配置目录下创建 docker-compose.yml,内容如下:

services:
  openclaw-gateway:
    image: ${OPENCLAW_IMAGE:-openclaw:local}
    container_name: openclaw-gateway
    environment:
      HOME: /home/node
      TERM: xterm-256color
      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
      OPENCLAW_ALLOW_INSECURE_PRIVATE_WS: ${OPENCLAW_ALLOW_INSECURE_PRIVATE_WS:-}
      CLAUDE_AI_SESSION_KEY: ${CLAUDE_AI_SESSION_KEY:-}
      CLAUDE_WEB_SESSION_KEY: ${CLAUDE_WEB_SESSION_KEY:-}
      CLAUDE_WEB_COOKIE: ${CLAUDE_WEB_COOKIE:-}
      TZ: Asia/Shanghai
      GATEWAY_TRUSTED_PROXIES: 172.18.0.0/16
      GATEWAY_CONTROLUI_ALLOWEDORIGINS: https://your-custom-domain
    expose:
      - "18789"
    volumes:
      - ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
      - ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
      ## Uncomment the lines below to enable sandbox isolation
      ## (agents.defaults.sandbox). Requires Docker CLI in the image
      ## (build with --build-arg OPENCLAW_INSTALL_DOCKER_CLI=1) or use
      ## docker-setup.sh with OPENCLAW_SANDBOX=1 for automated setup.
      ## Set DOCKER_GID to the host's docker group GID (run: stat -c '%g' /var/run/docker.sock).
      # - /var/run/docker.sock:/var/run/docker.sock
    # group_add:
    #   - "${DOCKER_GID:-999}"
    networks:
      - tunnel
    ports:
      - "${OPENCLAW_GATEWAY_PORT:-18789}:18789"
      - "${OPENCLAW_BRIDGE_PORT:-18790}:18790"
    init: true
    restart: unless-stopped
    command:
      [
        "node",
        "dist/index.js",
        "gateway",
        "--bind",
        "${OPENCLAW_GATEWAY_BIND:-lan}",
        "--port",
        "18789",
        "--allow-unconfigured"
      ]
    healthcheck:
      test:
        [
          "CMD",
          "node",
          "-e",
          "fetch('http://127.0.0.1:18789/healthz').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))",
        ]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 20s

  openclaw-cli:
    image: ${OPENCLAW_IMAGE:-openclaw:local}
    container_name: openclaw-cli
    network_mode: "service:openclaw-gateway"
    cap_drop:
      - NET_RAW
      - NET_ADMIN
    security_opt:
      - no-new-privileges:true
    environment:
      HOME: /home/node
      TERM: xterm-256color
      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
      OPENCLAW_ALLOW_INSECURE_PRIVATE_WS: ${OPENCLAW_ALLOW_INSECURE_PRIVATE_WS:-}
      BROWSER: echo
      CLAUDE_AI_SESSION_KEY: ${CLAUDE_AI_SESSION_KEY:-}
      CLAUDE_WEB_SESSION_KEY: ${CLAUDE_WEB_SESSION_KEY:-}
      CLAUDE_WEB_COOKIE: ${CLAUDE_WEB_COOKIE:-}
      TZ: Asia/Shanghai
    volumes:
      - ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
      - ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
    stdin_open: true
    tty: true
    init: true
    entrypoint: ["node", "dist/index.js"]
    depends_on:
      - openclaw-gateway

networks:
  tunnel:
    external: true

配置说明

两个服务:

  1. openclaw-gateway:主服务,提供 Web 控制面板和 websocket 网关
  2. openclaw-cli:命令行工具容器,用于执行 openclaw 命令

关键环境变量:

变量名 作用 示例值
OPENCLAW_GATEWAY_TOKEN 控制面板访问 token openssl rand -hex 32
OPENCLAW_GATEWAY_PORT gateway 端口映射 18789(默认)
OPENCLAW_BRIDGE_PORT websocket 桥接端口 18790(默认)
OPENCLAW_GATEWAY_BIND 绑定地址 lan(仅局域网), all(所有)
TZ 时区,确保日志时间正确 Asia/Shanghai
GATEWAY_TRUSTED_PROXIES 信任的反代 IP 段 172.18.0.0/16
GATEWAY_CONTROLUI_ALLOWEDORIGINS 允许访问控制面板的域名 https://your-domain.com

设置环境变量文件

为避免在命令行重复输入,可以创建 .env 文件:

cat > .env << EOF
export OPENCLAW_CONFIG_DIR="/home/gitop/.openclaw"
export OPENCLAW_WORKSPACE_DIR="/home/gitop/.openclaw/workspace"
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
export OPENCLAW_GATEWAY_TOKEN="your_secure_token"
EOF

docker compose 会自动加载 .env 文件中的变量。

自定义说明

相比官方 docker-compose.yml 的主要改动:

  • 时区设置:添加 TZ: Asia/Shanghai,确保容器内日志时间为北京时间
  • 代理信任:若使用 Cloudflared 等反代,需设置 GATEWAY_TRUSTED_PROXIES 为 Docker 子网段(默认 172.18.0.0/16),否则 WebSocket 连接会失败
  • 域名白名单:通过 GATEWAY_CONTROLUI_ALLOWEDORIGINS 允许自定义域名访问控制面板
  • 端口暴露expose 将 18789 端口暴露给同一 Docker 网络内的其他容器

初始化 OpenClaw

docker-compose.yml 所在目录执行:

docker compose run --rm openclaw-cli openclaw setup

初始化流程与 NPM 安装方式相同,后续如需重新进入交互式配置,可使用:

docker compose run --rm -it openclaw-cli onboard

启动服务

docker compose up -d openclaw-gateway

查看运行状态:

docker compose ps

openclaw-gateway 显示 healthy,表示启动成功。查看日志:

docker compose logs -f openclaw-gateway

访问控制面板

如果已将域名解析到 VPS 并配置 Cloudflare Tunnel 等反代,访问 https://your-custom-domain,输入 OPENCLAW_GATEWAY_TOKEN 进行登录。初次访问会提示需要配对设备。这是因为 OpenClaw 默认只允许本地访问,需要授权新设备。

配对步骤

  1. 查看待配对设备列表:

    docker exec openclaw-gateway cat /home/node/.openclaw/devices/pending.json

    复制其中的 deviceId(类似 abc123...

  2. 授权设备:

    docker exec openclaw-gateway openclaw devices approve your-device-id
  3. 刷新浏览器页面,即可进入控制面板。

配对成功后,该设备会被记录到 devices/paired.json,下次无需重复授权。

总结

Docker 方案更适合生产环境,配合 Cloudflare Tunnel 可实现内网服务的外网安全访问,无需开放额外端口。后续如需添加模型、通道或插件,直接修改 openclaw.json 并重启 openclaw-gateway 即可。祝养虾愉快 🦞!