FREE GUIDE Plan 1c · Tested 2026-07-21

Run OpenClaw Safely
on a $5 VPS

30 minutes · 10 steps · Every command verified on a clean Hetzner CX22

Want the full version? Monitoring, alerting, backup automation, and multi-agent configs.

Get the Full Pack →

What You'll End Up With

Prerequisites

Never run commands you don't understand. Every command below is explained. If something breaks, check the troubleshooting section.

Step 1: Initial SSH Hardening

SSH into your new VPS as root:

ssh root@YOUR_VPS_IP

1a. Create a non-root user

adduser --gecos "" openclaw
usermod -aG sudo openclaw

1b. Copy your SSH key

From your local machine:

ssh-copy-id openclaw@YOUR_VPS_IP

1c. Disable password authentication

sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd
Verify: Open a new terminal and SSH in as openclaw. If it works and ssh root@YOUR_VPS_IP is refused, you're good.

Step 2: Firewall

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw --force enable
Verify: sudo ufw status should show only 22, 80, 443 allowed.

Step 3: fail2ban

sudo apt update && sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban

Default config bans after 5 failed SSH attempts for 10 minutes.

Step 4: Automatic Security Updates

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# Select "Yes" when prompted

Step 5: Install Node.js

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node --version  # Should show v22.x.x

Step 6: Install OpenClaw

sudo npm install -g openclaw

6a. Create the config directory

sudo mkdir -p /etc/openclaw
sudo chown openclaw:openclaw /etc/openclaw

6b. Create the workspace directory

sudo mkdir -p /opt/openclaw/workspace
sudo chown openclaw:openclaw /opt/openclaw/workspace

Step 7: Resource Limits

Create a systemd override to cap memory at 3.5GB (leaves 500MB for the OS):

sudo mkdir -p /etc/systemd/system/openclaw.service.d
sudo tee /etc/systemd/system/openclaw.service.d/limits.conf <<'EOF'
[Service]
MemoryHigh=3G
MemoryMax=3500M
CPUQuota=150%
EOF

Step 8: systemd Service

sudo tee /etc/systemd/system/openclaw.service <<'EOF'
[Unit]
Description=OpenClaw AI Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=openclaw
Group=openclaw
WorkingDirectory=/opt/openclaw/workspace
Environment=NODE_ENV=production
Environment=HOME=/home/openclaw
ExecStart=/usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=openclaw

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/etc/openclaw /opt/openclaw/workspace /home/openclaw
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable openclaw
sudo systemctl start openclaw
Verify: sudo systemctl status openclaw should show "active (running)".

Step 9: Log Rotation

sudo tee /etc/logrotate.d/openclaw <<'EOF'
/var/log/openclaw/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 openclaw openclaw
}
EOF

Step 10: HTTPS with Caddy

sudo apt install -y caddy

Edit /etc/caddy/Caddyfile:

yourdomain.com {
    reverse_proxy localhost:3000
}
sudo systemctl restart caddy

Caddy automatically provisions Let's Encrypt certificates. No certbot needed.

Verification Checklist

CheckCommandExpected
Service runningsystemctl is-active openclawactive
Password SSH disabledssh -o PasswordAuthentication=yes root@IPPermission denied
Root login disabledssh root@IPPermission denied
Firewall activesudo ufw statusOnly 22/80/443
fail2ban runningsudo systemctl is-active fail2banactive
Memory limit setsystemctl show openclaw | grep MemoryMax3500M

Troubleshooting

"Cannot find module" errors

which openclaw
ls /usr/lib/node_modules/openclaw/dist/

Service crashes on start

sudo journalctl -u openclaw -n 50 --no-pager

Out of memory (OOM kills)

free -h

If total is under 2GB, upgrade to a 4GB VPS.

Caddy won't get certificates

  1. Make sure DNS points to your VPS IP
  2. Make sure port 80 is open: sudo ufw allow 80/tcp
  3. Check logs: sudo journalctl -u caddy -n 20

Hardening Extras (Optional)

Swap file (2GB safety net)

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Rate-limit SSH further

Add to /etc/ssh/sshd_config:

MaxAuthTries 3
LoginGraceTime 30

Then sudo systemctl restart sshd.

This is the free version. The full Operator Playbook Pack includes monitoring, alerting, backup automation, and multi-agent configs.

Get the Full Pack →