2026 OpenClaw Linux VPS
非 Docker 生产部署 Ubuntu 24.04 · systemd 常驻 · Cloudflare Tunnel 网关不直出公网

已经能装 OpenClaw、但不想把 Gateway 裸绑公网口的开发者,常在 Ubuntu 24.04 一类 VPS 上卡住:监听地址怎么选、systemd 如何做到可预期重启、Cloudflare Tunnel(或等价方案)怎样只把回环端口暴露给受控域名。本文给出与 Docker 生产篇、三平台安装篇互补的「裸机 + 系统服务 + 隧道」路径:环境基线、Gateway 配置要点、Unit 示例、隧道路由与按症状排障,并顺带画出与稳定远程 Mac 常驻结合的常见拓扑。

01

这篇和 Docker 生产篇、三平台安装篇各自解决什么问题

三平台安装篇负责把「能跑起来」的入口讲清楚;Docker 生产篇适合已经容器化、希望用 Compose 或编排平台统一交付的团队。本文面向另一类读者:希望在裸机 Ubuntu 24.04上用最少的抽象层跑 Gateway,用 systemd 承接崩溃恢复与开机自启,再用 Cloudflare Tunnel(或自建反向代理)把 TLS 与访问控制从应用里剥离出去。三条路径不是互斥的——你可以先在裸机跑通,再决定是否镜像化。

下面六个痛点,是我们在排障工单里最常见的「认知差」。把它们对齐后,后面的检查表才有意义。

  1. 01

    把「能 curl 通」当成「生产安全」:在 0.0.0.0 上开监听而不做前置代理,等于把认证与 TLS 全部压在应用默认值上;一次配置漂移就可能整网扫描。

  2. 02

    忽略 Node 运行时与 glibc 的耦合:Ubuntu 24.04 上混用旧版预编译二进制或错配 NODE_OPTIONS,会出现「本地能跑、服务起不来」的假阳性。

  3. 03

    工作目录与权限随手写 /root:升级脚本或日志轮转一旦改权限,Gateway 读配置失败会在 systemd 里表现为连续重启,日志却被淹没在上层。

  4. 04

    健康检查只测进程在不在:不验证 HTTP 就绪与上游模型连通性时,负载均衡仍会把流量打进来,隧道侧却返回 502,排障方向会完全跑偏。

  5. 05

    隧道通了但路由指错端口:cloudflared 的 ingress 与 Gateway 实际监听不一致时,外网域名能解析、内网却永远连不到正确回环端口。

  6. 06

    把 Linux 网关当「全能执行机」:需要 Xcode、模拟器或 Apple Silicon 特性的任务硬塞在 VPS 上,会把问题伪装成「OpenClaw 不稳定」,本质是拓扑放错层。

读完这一节,你应该能明确:自己是否要走「回环监听 + 隧道」这条线;若答案是肯定的,继续看环境与分步命令。

02

部署形态对比:直接暴露、Docker 与 systemd + Tunnel

选型时别只比较「安装快不快」,要把攻击面、可观测性、回滚路径放在同一行。下表用于评审对齐,具体端口与镜像版本请替换为你环境内的真实值。

维度Gateway 直绑公网Docker / Compose 生产systemd + 回环 + Tunnel
暴露面最大;依赖应用层 TLS 与防火墙规则由 publish 端口与网络模式决定,易误配 host 网络进程仅监听 127.0.0.1;公网入口在隧道或边缘
证书与域名需自建 ACME 或手工轮换常外挂 Traefik / Caddy 或云 LBCloudflare 边缘终止 TLS(或等价)
重启与排障依赖外部守护或手动restart policy + 日志驱动需单独设计systemd 内置重启策略与 journal 顺序清晰
适合团队极简 PoC,不建议生产已有容器规范与镜像供应链单台 VPS、要可脚本化复现的中小团队

生产网关的关键不是「能不能访问」,而是「谁在什么路径上被授权访问」——把监听缩到回环,是把这个问题从应用挪到更擅长的边缘层。

03

环境与依赖:Node、目录权限与防火墙基线

以 Ubuntu 24.04 LTS 为例,建议跟随 Node.js 当前 LTS 主版本(截至 2026 年初通常为 22.x 或官方文档推荐线,请以 nodejs.org 为准),用 nvm、fnm 或 NodeSource 均可,但生产环境请固定 minor 版本号并记录升级窗口。系统包管理器里的 node 往往偏旧,不适合作为 Gateway 的唯一来源。

防火墙基线建议:SSH 仅密钥、ufw 默认 deny incoming,不要为 Gateway 业务端口开公网规则——外网只走隧道。若必须直连调试,用限时白名单或跳板机,并在变更记录里写明撤销时间。

  1. 01

    创建专用用户与目录:例如 openclaw 用户,家目录外单独建 /var/lib/openclaw 存运行态,/etc/openclaw 存配置(权限 640 / 目录 750),避免混在 root 下。

  2. 02

    安装固定版 Node 与包管理器锁文件:在仓库或部署机保留 package-lock.json / pnpm-lock.yaml,生产安装使用 npm ci 或等价,杜绝「装包时顺手 major 升级」。

  3. 03

    校验 glibc 与原生依赖:若 Gateway 依赖带原生扩展的模块,先在目标机执行一次干净安装与冒烟脚本,确认无 dlopen 失败。

  4. 04

    配置时区与日志时间:timedatectl 设为 UTC 或团队统一时区,便于与隧道与边缘日志关联。

  5. 05

    启用 ufw 基线:ufw allow OpenSSHufw enable;业务端口保持关闭,确认 ss -tlnp 中外网侧看不到 Gateway 监听。

  6. 06

    预留健康检查端点:在正式挂隧道前,用 curl -fsS http://127.0.0.1:PORT/health(路径以你的配置为准)写进 Runbook,确保与 systemd 的 ExecStartPost 或外部探针一致。

info

提示:OpenClaw 具体子命令与配置文件名以官方文档为准;下文 Unit 与 YAML 中的路径、端口均为可替换占位,请按你实际安装位置修改后再启用。

04

Gateway 配置、systemd 与 Cloudflare Tunnel 路由

监听地址:生产推荐 127.0.0.1:PORT,必要时可再加 Unix domain socket(若你的版本支持)。令牌:通过环境文件注入,拒绝写进 world-readable 的配置;轮换时先写新令牌、滚动重启、再删旧令牌。健康检查:至少覆盖进程存活、HTTP 就绪与「能到达模型控制面」三层中的一层半——否则隧道只会告诉你「连不上」,不会告诉你「连错层了」。

systemd Unit 示例(请替换路径与参数)

/etc/systemd/system/openclaw-gateway.service
[Unit]
Description=OpenClaw Gateway (loopback)
After=network-online.target
Wants=network-online.target

[Service]
User=openclaw
Group=openclaw
WorkingDirectory=/var/lib/openclaw
EnvironmentFile=-/etc/openclaw/gateway.env
# 将 ExecStart 换成官方文档中的实际启动命令
ExecStart=/usr/bin/node /opt/openclaw/gateway.mjs --config /etc/openclaw/gateway.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576

# 日志:优先 journal;如需文件,配合 logrotate 与权限
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

启用顺序建议:systemctl daemon-reloadsystemctl enable --now openclaw-gatewaysystemctl status 看主进程是否稳定 → 本机 curl 健康检查 → 再启 cloudflared。

cloudflared:仅回环上游(示例)

config.yml 片段
tunnel: <YOUR_TUNNEL_ID>
credentials-file: /etc/cloudflared/<YOUR_TUNNEL_ID>.json

ingress:
  - hostname: claw.example.com
    service: http://127.0.0.1:8787
  - service: http_status:404
warning

注意:隧道凭证 JSON 权限应限制为 root 或专用用户可读;不要把凭证打进应用镜像层或公共 CI 日志。若使用自建 Nginx/Caddy 代替 Cloudflare,同样保持「边缘终止 TLS、上游仅回环」的结构即可。

日志查看顺序(排障时按此顺序扫一遍):journalctl -u openclaw-gateway -b --no-pager 看崩溃循环与环境变量是否加载;② 应用自身日志目录(若有);③ journalctl -u cloudflared 或等价隧道服务;④ 最后用 curl -v 从本机与外网各测一次,区分「进程问题」与「路由问题」。

05

常见报错分症状处理与和远程 Mac 结合的拓扑

端口类:EADDRINUSE 先用 ss -tlnp 找占用者,确认不是上一次僵尸进程;改端口后记得同步隧道 ingress 与内部探针。权限类:EACCES 查配置与密钥文件的 owner/group,systemd 的 User 必须与可读身份一致。隧道未通:外网 502 而本机 curl 正常,优先查 ingress 规则、隧道进程是否连上 Cloudflare、以及 DNS 是否指到正确 zone。模型连通性:Gateway 日志若出现超时或 401,先在服务器上直接 curl 模型供应商的基线接口(注意别把密钥写进 shell history),排除「出口 IP 被拦」与「令牌过期」。

典型拓扑是:Linux VPS 承载对外 Gateway、队列与轻量编排;稳定远程 Mac(物理 Apple Silicon)承载 Xcode 构建、模拟器与仅 macOS 可用的工具链。Gateway 收到任务后,将重活分发到 Mac 执行层——这样既满足「网关不直出公网」的安全诉求,又不在 Linux 上硬跑不擅长的工作负载。站点侧可把 Mac 当作可订购的执行节点,把 Linux 当作你自管的控制面,两者用 SSH、队列或内网隧道衔接均可,关键是把失败域切开:网关挂了不影响 Mac 上已有构建缓存,Mac 维护窗口也不应拖垮整个 API 入口。

  • 建议的 Gateway 监听:生产环境固定 127.0.0.1 + 单一端口,避免双栈误监听 IPv6 全网卡。
  • 建议的 systemd 重启策略:Restart=on-failure 配合 RestartSec=5,比无限瞬启更容易留下可读日志;必要时加 StartLimitIntervalSec 防止雪崩。
  • 建议的隧道上游:显式写 http://127.0.0.1:PORT 而非 localhost,减少解析到 IPv6 ::1 而应用只绑 IPv4 的坑。

单纯「一台 Linux VPS + 隧道」适合控制面与 API 聚合,但在 iOS CI/CD、模拟器、Metal 与 Xcode 链上会遇到硬边界:要么接受远程无头环境的兼容性折损,要么持续投入额外镜像与维护人力。相较之下,把重活放在可独占、可预期维护窗口的 Apple Silicon 远程 Mac上,网关层继续用你熟悉的 systemd 与隧道方案,整体失败域更清晰。对于需要长期稳定跑 Agent 与构建流水线的团队,NodeMini 的 Mac Mini 云端租赁通常是更优解——控制面仍可放在自管 VPS,执行面则交给与苹果生态对齐的硬件与租期组合。

FAQ

常见问题

生产强烈建议只监听回环,由隧道或反向代理承接 TLS 与访问策略。若必须对公网开放端口,应叠加防火墙白名单、限流与审计;复杂度通常高于隧道方案。更多 OpenClaw 主题文章见 OpenClaw 专栏

先在服务器本机 curl 回环地址确认 Gateway 真就绪;再查隧道服务的 ingress 与凭证;最后才怀疑上游模型或 DNS。订购执行节点前可先看 租赁价格说明 对齐租期与地区。

SSH/VNC 与常见故障可检索 帮助中心;博客目录在 博客首页