How We Set Up Your OpenClaw VPS
This is the exact setup we use for every OpenClaw deployment. Not a generic "getting started" guide — the real checklist, including the security steps most tutorials skip, and how we hand it off to you so you can actually use it from day one.
In this guide
1. Provision the server
We use Hetzner Cloud for most setups — German infrastructure, GDPR-compliant, and the cheapest serious provider we've found. Settings for a new server:
- Image: Ubuntu 22.04 or 24.04 LTS
- Type: CX22 (2 vCPU, 4GB RAM) at €3.79/month — sufficient for most setups
- Location: Nuremberg or Helsinki for EU data residency
- SSH key: Add your public key during creation — not after
💡 No SSH key yet? Run ssh-keygen -t ed25519 on your own machine. Your public key is at ~/.ssh/id_ed25519.pub — paste that into Hetzner's SSH key field.
2. SSH hardening + non-root user
Log in as root once to configure a proper user account. OpenClaw will run as this user — not as root. The user has sudo access for system commands (package installs, firewall rules), but OpenClaw's day-to-day operations never touch root.
Create a dedicated user and copy your SSH key to them:
adduser openclaw usermod -aG sudo openclaw mkdir -p /home/openclaw/.ssh cp ~/.ssh/authorized_keys /home/openclaw/.ssh/ chown -R openclaw:openclaw /home/openclaw/.ssh
Disable root login and password authentication. Edit /etc/ssh/sshd_config:
PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes
systemctl restart ssh
Change the default SSH port from 22 to something non-standard. This doesn't stop a determined attacker, but eliminates the constant background noise of automated bots scanning port 22.
# In /etc/ssh/sshd_config, change: Port 2222 # or any port 1024–65535 # Then: allow the new port before restarting SSH ufw allow 2222/tcp systemctl restart ssh
⚠️ Open a second terminal and test the new port before closing the current session: ssh -p 2222 openclaw@YOUR_IP. Only close your root session after you've confirmed it works.
3. Firewall
apt install ufw -y ufw allow 2222/tcp # your SSH port (change if different) ufw allow 443/tcp # HTTPS — only if serving web content ufw enable
Default policy is deny-all inbound. Everything not explicitly allowed stays closed. Check at any time with ufw status.
4. Brute-force protection (fail2ban)
fail2ban watches your SSH logs and automatically bans IPs after too many failed login attempts. Even with SSH keys required, this keeps your logs clean and blocks credential stuffing attempts.
apt install fail2ban -y systemctl enable fail2ban systemctl start fail2ban
The default configuration protects SSH out of the box. To verify it's working:
fail2ban-client status sshd
4b. Automatic OS security updates
unattended-upgrades automatically installs security patches for the OS without you having to do anything. Ubuntu often has it installed by default — but it's worth verifying it's actually running:
systemctl is-active unattended-upgrades
If it's not running:
apt install unattended-upgrades -y dpkg-reconfigure -plow unattended-upgrades
This handles OS-level patches. OpenClaw itself you update separately — via the weekly cron we set up.
5. Remote access with Tailscale
Tailscale creates a private, encrypted network between your devices — your phone, laptop, and VPS all become peers. This means you can access your VPS (and anything running on it) from anywhere without opening additional firewall ports.
curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up
Scan the QR code or visit the auth URL to link the server to your Tailscale account. Once connected, your VPS is accessible at its Tailscale IP (something like 100.x.x.x) from any of your other devices on the same account — even if you're behind a NAT or on mobile data.
This is also how we can access your setup remotely for support without needing to open public ports.
6. Install Node.js + OpenClaw
Ubuntu's default Node.js is outdated. OpenClaw requires version 22+:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt install -y nodejs node --version # should show v22.x.x
npm install -g openclaw@latest openclaw onboard --install-daemon
The onboarding wizard handles: connecting your AI provider, setting up channels, and installing the gateway as a systemd service (so OpenClaw restarts automatically after reboots).
7. Reverse proxy with nginx
If you want to expose a web dashboard or other service via a domain name (with HTTPS), you need a reverse proxy sitting in front. nginx handles incoming HTTPS traffic and forwards it to the right local service.
sudo apt install nginx -y
A basic site config at /etc/nginx/sites-available/your-domain:
server {
listen 443 ssl;
server_name dashboard.yourdomain.com;
# SSL via Cloudflare Tunnel — no Let's Encrypt needed
# if self-managing TLS, use certbot here instead
location / {
proxy_pass http://127.0.0.1:8100;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
We typically use Cloudflare Tunnel in front of nginx rather than opening port 443 directly — your server's IP stays private, SSL is handled by Cloudflare, and you get DDoS protection for free.
8. Connect your channels
Telegram
The simplest channel to connect. Takes 2 minutes:
- Open Telegram, message @BotFather
- Send
/newbot, follow the prompts, copy your bot token - Add the token to your OpenClaw config (
~/.openclaw/openclaw.json) underchannels.telegram.botToken - Restart the gateway:
openclaw gateway restart - Message your new bot — it responds immediately
OpenClaw connects via WhatsApp Web (the same mechanism as scanning a QR code in a browser) — not the paid WhatsApp Business API. This means it's free and works with any regular WhatsApp number.
- We recommend a dedicated WhatsApp number (a second SIM or an eSIM) to keep your personal WhatsApp separate
- Run
openclaw channels login --channel whatsappand scan the QR code with your phone - The session is then maintained on your VPS — your phone doesn't need to stay online
💡 For the handoff: we run the QR pairing step on a video call so you scan it yourself. Takes 30 seconds.
9. Memory safety + OOM prevention
A 4GB VPS is enough for most setups, but AI agents, node processes, and background services can accumulate. Without protection, a memory spike kills the server — it either becomes unresponsive or the OOM killer starts terminating random processes, including OpenClaw.
Swap
Swap acts as a pressure valve — when RAM fills up, the system can use disk space temporarily instead of crashing immediately. Most VPS providers don't set it up by default:
fallocate -l 2G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile none swap sw 0 0' >> /etc/fstab
systemd memory limits
Capping how much memory OpenClaw's service can use prevents a runaway process from taking down the whole server. In the systemd service file:
[Service] MemoryMax=1G MemorySwapMax=512M
OOM score tuning
The Linux OOM killer decides what to kill when memory runs out. Lower score = more protected. Protect your SSH daemon so you never lose remote access:
echo -1000 > /proc/$(pgrep sshd)/oom_score_adj
10. OpenClaw configuration — critical settings
After installation, a few settings in ~/.openclaw/openclaw.json are non-negotiable on a VPS. The defaults are designed for local/home use — a public server needs these explicitly set:
{
"gateway": {
"bind": "loopback", // NEVER "lan" — keeps gateway off public internet
"auth": { "mode": "token", "token": "64-random-chars" },
"tailscale": { "mode": "serve" }
},
"discovery": {
"mdns": { "mode": "off" } // mDNS is useless on a VPS and adds noise
},
"channels": {
"telegram": { "dmPolicy": "pairing" } // Unknown senders blocked until you approve
}
}
Run openclaw doctor after any config change — it catches misconfigurations. Run openclaw security audit --deep weekly to verify nothing has drifted.
11. 3-2-1 Backups
The 3-2-1 rule: 3 copies of your data, on 2 different media, with 1 offsite. Your workspace folder is your AI's memory, automations, and configuration — losing it means starting over.
Copy 1: Local daily backup
A daily cron job that rsyncs your workspace to a separate directory on the same server:
#!/bin/bash rsync -a --delete \ --exclude='node_modules/' --exclude='.git/' \ ~/workspace/ ~/backups/workspace-$(date +%Y-%m-%d)/ # Keep last 7 days find ~/backups -maxdepth 1 -name "workspace-*" -type d | sort | head -n -7 | xargs rm -rf
Copy 2: Hetzner Snapshot
A weekly server snapshot captures the full disk state, including the OS and all installed software. In Hetzner Cloud Console: Servers → your server → Snapshots → Take snapshot. Costs ~€0.01/GB/month.
Copy 3: Offsite (Backblaze B2 or Hetzner Storage Box)
Use rclone to push your workspace to cloud storage automatically:
rclone copy ~/workspace b2:your-bucket/workspace --exclude "node_modules/**"
Two good options for offsite storage:
- Backblaze B2 — $0.006/GB/month. 100MB workspace costs less than €0.01/month. Use rclone with the B2 provider.
- Hetzner Storage Box — starts at €3.19/month for 1TB. Stays in the EU (Germany), connects via SFTP/rsync. Good fit if you're already on Hetzner and prefer everything in one place.
# Hetzner Storage Box via rsync rsync -az --delete -e "ssh -p 23" \ ~/workspace/ [email protected]:workspace/
If you have Hetzner automatic VPS backups enabled (in the Cloud Console), that's your Copy 2 — a weekly full-disk snapshot. Storage Box is your Copy 3 (workspace only, daily, offsite).
Sources
Rather have us do this for you?
We handle the full setup — server, hardening, channels, memory limits, backups. You get a working system and a 30-minute walkthrough. Nothing for you to figure out.
Book a free call →