Deploy OpenClaw to a $5 VPS with Cloudflare Tunnel (No Public IP Needed)

Step-by-step guide to run OpenClaw on a bargain VPS, secure it with a Cloudflare Tunnel, and keep maintenance near-zero.

February 2, 2026

Most VPS boxes ship with a public IP, open ports, and a big attack surface. You can run OpenClaw safely on a $5 VPS without exposing any ports by fronting it with Cloudflare Tunnel. This guide walks you through provisioning, securing, and updating—end-to-end.

What you'll set up

  • A minimal Ubuntu VPS (or any Debian-based host)
  • OpenClaw running behind Cloudflare Tunnel (no inbound ports open)
  • TLS handled by Cloudflare, origin locked down with a firewall
  • Systemd service for reliability + zero-downtime updates

Prerequisites

  • A domain managed in Cloudflare
  • Cloudflare account with tunnel access (free is fine)
  • VPS running Ubuntu 22.04+ (other distros work with minor tweaks)
  • Node.js 20+ (OpenClaw target) and pnpm 9.x installed

1) Prep the VPS

Update base packages and install essentials:

zsh
 sudo apt update && sudo apt upgrade -y
 sudo apt install -y curl git ufw

Install Node.js 20 and pnpm:

zsh
 curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
 sudo apt install -y nodejs
 corepack enable
 corepack prepare pnpm@9 --activate

Add a non-root deploy user (recommended):

zsh
 sudo adduser --disabled-password --gecos "" openclaw
 sudo usermod -aG sudo openclaw
 sudo su - openclaw

2) Install Cloudflare Tunnel (cloudflared)

zsh
 curl -fsSL https://developers.cloudflare.com/cloudflare-one/static/documentation/connections/connect-apps/install-and-setup/tunnel-run.sh | sudo bash
 cloudflared tunnel login   # opens browser to authenticate
 cloudflared tunnel create openclaw-vps

Grab the tunnel UUID from the output; you'll need it in the config file.

3) Clone and configure OpenClawVPS

zsh
 cd ~
 git clone https://github.com/openclaw/openclawvps.git
 cd openclawvps
 pnpm install

Create your environment file with required secrets (example):

zsh
 cp .env.example .env
# Edit with your values

Key values to set:

  • ANTHROPICAPIKEY (or OpenAI key if configured)
  • NEXTPUBLICAPP_URL=https://yourdomain.com
  • GATEWAY_TOKEN and any provider tokens you use

4) Lock down the firewall

Allow only outbound + SSH, block inbound HTTP/HTTPS (tunnel will handle edge TLS):

zsh
 sudo ufw default deny incoming
 sudo ufw default allow outgoing
 sudo ufw allow OpenSSH
 sudo ufw enable
 sudo ufw status

5) Wire the Cloudflare Tunnel to your local port

Create /etc/cloudflared/config.yml:

yaml
tunnel: <YOUR_TUNNEL_UUID>
credentials-file: /home/<user>/.cloudflared/<YOUR_TUNNEL_UUID>.json

ingress:
  - hostname: yourdomain.com
    service: http://localhost:3000
  - hostname: www.yourdomain.com
    service: http://localhost:3000
  - service: http_status:404

Start the tunnel as a service:

zsh
 sudo cloudflared service install
 sudo systemctl enable cloudflared
 sudo systemctl start cloudflared
 sudo systemctl status cloudflared

6) Add a systemd service for OpenClaw

Create /etc/systemd/system/openclaw.service:

ini
[Unit]
Description=OpenClaw VPS
After=network.target cloudflared.service

[Service]
Type=simple
User=openclaw
WorkingDirectory=/home/openclaw/openclawvps
Environment=NODE_ENV=production
EnvironmentFile=/home/openclaw/openclawvps/.env
ExecStart=/usr/bin/pnpm start
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Reload and start:

zsh
 sudo systemctl daemon-reload
 sudo systemctl enable openclaw
 sudo systemctl start openclaw
 sudo systemctl status openclaw

7) Zero-downtime updates

Pull and restart with no rebuild surprises:

zsh
 cd /home/openclaw/openclawvps
 git pull
 pnpm install --frozen-lockfile
 pnpm run build
 sudo systemctl restart openclaw

For safer rollouts, keep a cached build and swap only after success:

zsh
 pnpm run build && sudo systemctl restart openclaw

8) Observability quick wins

  • Health check: Add an uptime monitor to https://yourdomain.com/health (or a simple /api/ping).
  • Logs: journalctl -u openclaw -f for live app logs; journalctl -u cloudflared -f for tunnel issues.
  • Rate limiting: Use Cloudflare WAF rules to throttle abusive IPs before they hit the tunnel.

9) Security hardening checklist

  • Keep SSH on key auth, disable password login in /etc/ssh/sshd_config:
zsh
 PasswordAuthentication no
 PermitRootLogin prohibit-password

Then sudo systemctl reload sshd.

  • Restrict sudo to your deploy user.
  • Rotate API keys periodically; store secrets in .env with least privilege.
  • Turn on Cloudflare bot fight mode and WAF managed rules.

10) Validation steps

  • curl -I https://yourdomain.com should return 200 and show cloudflare server header.
  • sudo ufw status should show only SSH allowed.
  • systemctl status openclaw should be active (running).
  • Visit your blog at https://yourdomain.com/blog and confirm dynamic OG/Twitter cards render from /api/og?title=....

Troubleshooting

  • Tunnel 502/522: Check cloudflared logs; ensure app is listening on 3000.
  • Mixed content warnings: Make sure NEXTPUBLICAPP_URL is https://....
  • Unexpected 404: Verify your ingress hostnames match the domain you visit.
  • Memory spikes: Use a small swap file on low-RAM VPS (sudo fallocate -l 1G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile).

---

With a Cloudflare Tunnel in front of your $5 VPS, you avoid open inbound ports, get automatic TLS, and can ship OpenClaw fast without waiting on firewall rules. Keep pnpm run build && systemctl restart as your update habit and you’ll have a stable, low-maintenance setup.

Share this post

Related Posts