01Running on a VPS #
Running OpenClaw on a VPS doesn't need a large machine. A Hetzner CX23 is plenty.
Put Tailscale on both your local machine and the VPS. Install it on the VPS with the --ssh=true flag and you can log in over Tailscale directly. Then block port 22 entirely in the Hetzner firewall.
Block all inbound traffic and reach everything over Tailscale. The Gateway itself stays on loopback; you reach its dashboard through an SSH tunnel or Tailscale Serve. A simple setup, and one less thing to worry about.
02Hardware requirements #
Minimum specs: a Hetzner CX23 or equivalent. That is enough for a native install; building the official Docker image from source needs a server with at least 6 GB of RAM.
- vCPUs
- 2
- RAM
- 4 GB
- Disk
- 40 GB
- Monthly cost
- ~$5/mo
03Network security with Tailscale #
Step 1: Install Tailscale on your local machine
# On your local machine (Mac/Linux/Windows)
# Visit: https://tailscale.com/download
# Install and authenticateStep 2: Install Tailscale on the VPS
# SSH into the VPS normally first
ssh user@your-vps-ip
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --ssh=trueThe --ssh=true flag enables SSH over Tailscale.
Step 3: Get the VPS Tailscale IP
# On the VPS, get your Tailscale IP
tailscale ip -4
# Example output: 100.64.1.2Step 4: Test SSH via Tailscale
# Use the Tailscale IP, NOT your public IP
ssh user@100.64.1.2Step 5: Block public access, only after verification
# 1. Create a new firewall rule
# 2. Block: all inbound traffic on port 22
# 3. Leave Tailscale traffic unrestricted (100.64.0.0/10)Step 6: Verify lockout prevention
# This should work (Tailscale)
ssh user@100.64.1.2
# This should fail/timeout (public IP blocked)
ssh user@your-public-vps-ip04OpenClaw installation #
The installer script sets up a supported Node runtime (24.16+ or 26.1+; Node 22 is no longer supported) and installs OpenClaw. Onboarding then writes your config and installs the Gateway as a systemd user service.
# Installs Node if needed (24.16+ or 26.1+), then OpenClaw
curl -fsSL https://openclaw.ai/install.sh | bash
# Onboard and install the systemd user service
openclaw onboard --install-daemonThen run these before doing anything else:
# Health checks, config migrations and guided repairs
openclaw doctor --fix
# Security audit, including a live Gateway probe
openclaw security audit --deepThe security audit should return zero critical issues. Warnings you may see:
fs.credentials_dir.perms_readable: runopenclaw security audit --fix, which tightens state and config permissionsgateway.trusted_proxies_missing: only fires when reverse-proxy headers reach the Gateway. Behind nginx or Caddy, setgateway.trustedProxies
05File permissions #
Lock down the config directory:
chmod 700 ~/.openclaw
chmod 600 ~/.openclaw/openclaw.json
chmod 700 ~/.openclaw/credentials This stops other users on the system from reading your config, credentials and the SQLite databases that hold auth profiles and transcripts. openclaw security audit --fix applies the same 700/600 permissions for you.
06Gateway binding and auth #
Verify the gateway binds to localhost and isn't exposed to the public internet:
ss -ltn | grep 18789
# You want to see: 127.0.0.1:18789
# You do NOT want: 0.0.0.0:18789Correct
127.0.0.1:18789
Only localhost can reach the gateway
Dangerous
0.0.0.0:18789
Anyone who can reach port 18789 can talk to your agent
Loopback is the default. Gateway auth is required too: with no token or password the Gateway refuses WebSocket connections, and startup rejects blank or placeholder secrets. Onboarding generates a token; openclaw doctor --generate-gateway-token makes a new one.
"gateway": {
"mode": "local",
"bind": "loopback",
"port": 18789,
"auth": { "mode": "token", "token": "<openssl rand -hex 32>" }
} To use the dashboard from your laptop, let OpenClaw run Tailscale Serve. The Gateway stays on 127.0.0.1 and Tailscale provides tailnet-only HTTPS:
"gateway": {
"bind": "loopback",
"tailscale": { "mode": "serve" }
}07Hardening configuration #
Logging and redaction
Redaction of log tails, console output and diagnostic exports is always on and no longer configurable; openclaw doctor --fix removes the retired redactSensitive switch. Add your own patterns for hostnames, internal URLs or custom token formats:
"logging": {
"redactPatterns": ["\\bTOKEN\\b\\s*[=:]\\s*(\\S+)"]
} The rolling files in /tmp/openclaw/ are raw (owner-only 0600), and tool arguments, tool results and transcripts are never masked. Treat them as secrets, and share openclaw status --all instead of raw logs.
Tool policies
Restrict which tools agents can use. A profile sets the base list; alsoAllow adds to it, and deny always wins:
"tools": {
"profile": "minimal",
"alsoAllow": ["read", "web_search", "web_fetch"]
}| minimal | session_status, plus gateway for updates only |
|---|---|
| coding | Files, exec, web, sessions, memory, cron, media |
| messaging | The message tool, session tools and status |
| full | No profile filtering (what onboarding sets) |
Sandbox mode (optional)
For containerized tool execution (requires Docker). Sandboxing is off by default; non-main sandboxes every session except your main one:
"agents": {
"defaults": {
"sandbox": {
"mode": "non-main",
"scope": "agent",
"workspaceAccess": "none",
"docker": { "image": "openclaw-sandbox:bookworm-slim" }
}
}
} Build the openclaw-sandbox:bookworm-slim image first. OpenClaw fails fast rather than falling back to a plain Debian image. Useful on a shared VPS where you want agent work isolated.
08Git-track your config #
Git-track the OpenClaw config directory so you can roll back:
cd ~/.openclaw && git init
# Track only the config; state lives in SQLite databases
printf '*\n!.gitignore\n!openclaw.json\n' > .gitignore
git add .gitignore openclaw.json
git commit -m "config: baseline"# Before making changes
git commit -am "config: before model update"
# Make your changes
vim openclaw.json
# Validate and commit
openclaw config validate
git commit -am "config: switch heartbeat model" When something breaks at midnight, git diff and git checkout are faster than trying to remember what you changed. Most config edits hot-reload; auth-mode changes need a Gateway restart.
09Validation workflow #
After any config change:
- 1
Validate
openclaw config validate - 2
Health check
openclaw doctor - 3
Security audit
openclaw security audit --deep - 4
Test
openclaw status, then send a test message - 5
Commit
git commit -am "config: description of change"
10System monitoring #
# Check OpenClaw status
openclaw status
# Service state and readiness
openclaw gateway status --deep
# Check for errors in recent logs
openclaw logs --plain --limit 500 | grep -i error
# Check system resources
htopConsider a cron job or heartbeat check for failed jobs and error logs. See the Heartbeat & Task Tracking chapter.
11Backup strategy #
Back up
- ~/.openclaw/ (config, credentials, SQLite state)
- Agent directories
- Workspaces
Never
- Raw copies of live .sqlite, -wal or -shm files
- Rolling logs in /tmp/openclaw/
- Sandbox runtimes (recreated)
State lives in SQLite databases that the Gateway writes continuously, so a plain tar of ~/.openclaw can capture a torn database. openclaw backup snapshots them safely while the Gateway runs.
Backup script
Create ~/bin/backup-openclaw.sh:
#!/bin/bash
# OpenClaw backup script
BACKUP_DIR=~/backups
mkdir -p $BACKUP_DIR
# Archive state, config, credentials, agents and workspaces.
# SQLite databases are captured safely while the Gateway runs.
openclaw backup create --output $BACKUP_DIR --verify
# Keep only the last 7 days of archives
find $BACKUP_DIR -name "*-openclaw-backup.tar.gz" -mtime +7 -delete
echo "$(date): backup completed" >> $BACKUP_DIR/backup.logchmod +x ~/bin/backup-openclaw.sh
crontab -e
# Daily at 3 AM
0 3 * * * ~/bin/backup-openclaw.sh
# Every 6 hours
0 */6 * * * ~/bin/backup-openclaw.sh
# Weekly on Sunday at 2 AM
0 2 * * 0 ~/bin/backup-openclaw.shOr let the Gateway schedule it
With a storage location configured (a disk or object store), the Gateway can create, verify, upload and prune backups itself:
# Gateway-owned daily backups to a configured storage location
openclaw backup enable --to offsite --every 24h --keep-daily 7 --keep-weekly 4
# Restore stages files into a fresh directory
openclaw backup restore <archive.tar.gz> --target ./restored-openclawArchives contain credentials and session history. Store them encrypted, and restrict the destination like the live state directory.
12Service management #
openclaw onboard --install-daemon installs a systemd user unit, openclaw-gateway.service, on Linux (launchd on macOS). On a headless VPS, enable lingering so the service survives logout.
# Check service status
openclaw gateway status
# or
systemctl --user status openclaw-gateway
# Manage the service
openclaw gateway start
openclaw gateway stop
openclaw gateway restart
# Keep the user service running after you log out
sudo loginctl enable-linger $(whoami)13Get stable before going 24/7 #
Don't run OpenClaw 24/7 until the basics are ironed out. Get your config right, get your agents stable, get your costs predictable. Then let it run.
People who jump to 24/7 operation on day one end up with a bot that burns $50 in API calls overnight because a retry loop went sideways.
14Troubleshooting #
Tailscale SSH not working
sudo tailscale status
sudo tailscale status | grep ssh
sudo tailscale up --ssh=trueCan't find the Tailscale IP
tailscale ip -4 # IPv4
tailscale ip -6 # IPv6
hostname # Machine name on the Tailscale networkGateway won't start
openclaw gateway status --deep
openclaw doctor --fix
openclaw gateway restartPort already in use
ss -ltnp | grep 18789
# Stop the other process or change gateway.portLocked out after a firewall change
- Use the provider's web console (Hetzner Console, DigitalOcean Droplet Console).
- Log in through the web interface.
- Fix the firewall rules or re-enable Tailscale.
- Test Tailscale SSH before closing the console.
15Pre-production security checklist #
Before running OpenClaw in production:
- File permissions locked down (700/600)
- Gateway binds to loopback with a long random auth token
- openclaw security audit --deep returns zero critical issues
- Tailscale configured, SSH blocked at the firewall
- DMs on pairing or allowlists, groups behind a mention
- Tool policies configured
- Config git-tracked, never pushed with tokens in it
- Backups run with openclaw backup and are verified
16Keeping the VPS cheap #
Running on a VPS doesn't have to be expensive:
- Hetzner CX23: ~$5/month
- A cheap, small model for heartbeats
- Cross-provider fallbacks to avoid quota burnout
- Concurrency limits to prevent runaway costs
See the Agent Prompts chapter for model configuration strategies.
Adapted from digitalknk/openclaw-runbook. OpenClaw changes fast: check the official docs before copying config into production.