2026: OpenClaw on Linux VPS Without Docker
Ubuntu 24.04, systemd, and Cloudflare Tunnel for a Loopback Gateway

About 18 min read · MACCOME

After the three-platform install and Docker production guides, you may still want OpenClaw Gateway on bare-metal Node + systemd atop Ubuntu 24.04, with Cloudflare Tunnel so the gateway does not listen on the public interface. This article gives scope vs Docker, pain-point decomposition, two tables, systemd and tunnel snippets, a six-step runbook, and three on-call metrics, linking to post-install triage, Docker production, install guide, and Gateway security advanced for reproducible go-live.

Six bare-metal pitfalls: more than “skip the container”

Bare metal pushes Node versions, permissions, bind addresses, and process supervision back onto the host. If you keep the “foreground Gateway on a laptop” habit, reboots drop services, journals lack structure, and ufw vs cloud SG drift makes incidents anecdotal. Decompose the six classes before copying configs.

  1. Node and global CLI drift: repeated sudo npm i -g upgrades desync prod from docs; pin ExecStart to a fixed Node binary or version-manager shim.
  2. Overly wide binds: 0.0.0.0 plus one missed firewall rule exposes the control plane; with tunnels, prefer 127.0.0.1 and let the tunnel accept inbound.
  3. systemd user vs WorkingDirectory mismatch: configs under root’s home while the unit runs as openclaw yields “works manually, fails under service.”
  4. Tunnel upstream port mismatch: cloudflared pointing at the wrong local port shows external 502 unrelated to model timeouts.
  5. Inbound vs outbound confusion: tunnels fix reachability from clients; model API, DNS, proxies, and keys still use outbound paths—triage per the post-install article.
  6. No rollback anchor: upgrading OpenClaw or Node without freezing the last known-good ExecStart and config hash blocks fast rollback.

Two tables compress Docker vs bare metal and tunnel vs direct reverse proxy for review packets.

The advanced Gateway security article covers tokens, exposure, and secret rotation; this article covers loopback bind on Linux hosts and handing ingress to a tunnel. Together they form “edge ingress, secrets in the repo plane, processes under systemd.” Complete onboarding and model keys via the install guide before production-hardening here.

Docker Compose vs bare-metal systemd: when to choose which

The Docker production post covers image pins, volumes, and Compose rollback; this post covers host units + tunnel. Table 1 is for architecture review—not a religious choice.

DimensionDocker / ComposeBare Node + systemd (this article)
ReproducibilityImages and digests lock runtimeHost stack varies; compensate with config management and version pins
Triage depthContainer logs and volume perms firstHost-level tools available when policy allows
Existing ops toolingNeeds container monitoring and registry flowReuse journald, node_exporter, backup scripts
Upgrade pathSwap image tags; volumes explicitNode and global packages move together—script rollback
Typical fitTeams already standardized on containersMust run on metal or couple tightly to legacy systemd services

Cloudflare Tunnel vs host reverse proxy: where to cut the boundary

Tunnels offload TLS and public ingress to the edge; Nginx/Caddy often terminate TLS locally and reverse-proxy to loopback. You may combine them, but listening surfaces must stay minimal. Use table 2 against security-group rules.

PatternGateway bindPublic surfaceOps notes
Tunnel to loopback127.0.0.1:PORT (per OpenClaw docs)No direct Gateway port; tunnel process egress onlyMatch ingress to the live local service port
Local Nginx/CaddyUsually still loopback upstream443 on proxy; manage certs and rate limitsTriple-check ufw and cloud SGs to avoid double exposure
Not recommended: Gateway on 0.0.0.0All interfacesControl plane on the internetRequires strict tokens, allowlists, and WAF—not default
ini
# /etc/systemd/system/openclaw-gateway.service (skeleton; ExecStart per official CLI)
[Unit]
Description=OpenClaw Gateway (bare metal)
After=network-online.target
Wants=network-online.target

[Service]
User=openclaw
Group=openclaw
WorkingDirectory=/var/lib/openclaw
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /path/to/openclaw/cli.js gateway start --bind 127.0.0.1
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
yaml
# cloudflared fragment: hostname to local Gateway
tunnel: YOUR_TUNNEL_ID
credentials-file: /etc/cloudflared/YOUR_TUNNEL.json

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

Note: Ports and binary paths are placeholders. Align with current OpenClaw docs and openclaw --help; record hashes and rollback commands in the change ticket.

Six steps: clean Ubuntu 24.04 to on-call systemd + tunnel

  1. Freeze baseline: kernel, Node minor, OpenClaw package version, OpenSSL—match minimums from the install guide.
  2. Create service user and dirs: dedicated user, clear ownership—avoid prod configs in a personal home while running as another account.
  3. Validate loopback first: bind 127.0.0.1, curl or health-check per docs, then add the tunnel.
  4. Author and enable systemd: daemon-reload && enable --now; tail journalctl -u openclaw-gateway -f for ordering errors.
  5. Configure cloudflared ingress: cloud DNS matches local config; classify external 502/525 as tunnel vs upstream.
  6. Practice upgrade and rollback: tarball last-good ExecStart and configs; fail forward only within your RTO.

Split local health (process + loopback port) from external health (DNS, cert chain, edge routing). Updating only one during releases causes “green inside, red outside” false positives. Ticket templates should require OpenClaw version, Node minor, and cloudflared version, plus a journal excerpt for audit trails.

Three on-call metrics

  1. Listening surface count: production should list every open TCP port in one line; public Gateway binds without WAF are urgent defects.
  2. Tunnel 502 triage: curl -v 127.0.0.1:PORT first, then tunnel logs; local fail = app layer, local pass / remote fail = tunnel or DNS.
  3. Outbound probe baseline: automate TLS and HTTP checks from the VPS to the model vendor; share thresholds with the post-install doctor steps.

Addendum: on small VPSes running only Gateway and tunnel, if latency jitters while CPU looks idle, check per-process file descriptors, long-lived WebSocket counts, and TLS RTT to providers before resizing vCPU.

Gap between “any VPS” and a stable execution layer

A generic Linux VPS runs demos, but IO variance and headless constraints still shape long-running automation. Production OpenClaw needs repeatable supervision, auditable listening surfaces, and alignment with CI and secret workflows.

For iOS builds, Simulator, or GUI triage, Linux cannot replace Apple Silicon; many teams place Gateway on a Linux edge and offload heavy Xcode work to remote Macs. Spare laptops and fragmented desktops struggle with 24/7 agents: sleep and prompts convert automation into random failure. MACCOME offers multi-region Mac Mini M4 / M4 Pro bare-metal—useful as a build and long-session backend while Linux converges ingress. Open the Help Center, then align rental rates with your region page.

Pilot with short rentals to measure end-to-end latency for “tunnel + remote Mac workload” before colocating ingress and compile roles on one host.

FAQ

Isn’t Docker enough?

Often yes—see Docker production. Bare systemd fits tight integration with existing host ops or host-level triage needs.

127.0.0.1 or 0.0.0.0 for Gateway?

Prefer loopback behind tunnel or local proxy; widen only with firewall, tokens, and monitoring. Validation steps live in post-install triage.

Where are install commands and platform differences?

Install and platform selection; pricing at rental rates.