The $6/mo AI Brain:
Hetzner CPX11 VPS Guide
/** A 24/7 cloud agent that costs less than a fast food meal. */
A cheap Linux VPS combined with a small model (4-bit Llama 3 8B) works perfectly for Telegram/WhatsApp replies, daily feed summarization, and web scraping. No $1000 GPU required.
1. Spin up the Hetzner Server
- Create a Hetzner Cloud account.
- Create a new project and select New Server.
- Location: Choose the datacenter closest to you.
- Image: Ubuntu 24.04 LTS.
- Type: Shared vCPU, CPX11 (2 vCPU, 2GB RAM, 40GB Disk).
- Add your SSH keys, then click Create.
2. Critical: Create Swap Space
2GB of RAM is not enough to load a 4GB+ LLM. We MUST create a swap file.
3. Deploy OpenClaw via Docker
Use Docker Compose to spin up OpenClaw and Ollama completely CPU-bound.
CPU Optimization Secrets
Which Hetzner plan, and what it actually gets you
Hetzner's cheap shared-vCPU plans have no GPU, so a VPS is a CPU-inference box. That is fine for orchestration and small models and painful for anything else. Size the plan around RAM first, because a model that does not fit will swap and the throughput difference is not subtle.
| Plan class | RAM | Realistic use |
|---|---|---|
| CX22 (2 vCPU) | 4 GB | Gateway, channels and skills, with the model hosted elsewhere. A 1Bβ3B model fits but is slow. |
| CX32 (4 vCPU) | 8 GB | A 3B model locally with room for the gateway and a database. The usual sweet spot for a self-hosted agent. |
| CX42 (8 vCPU) | 16 GB | 7Bβ8B on CPU. It runs, but expect single-digit tokens per second; suitable for batch, not chat. |
| Dedicated vCPU | varies | Worth it only if you are hitting steal time on shared vCPU. Check before paying for it. |
CPU inference on a shared vCPU plan is roughly an order of magnitude slower than the same model on Apple Silicon, and shared plans can also suffer steal time from noisy neighbours. If you want a local model to feel interactive, a VPS is the wrong shape β use the VPS for the always-on gateway and point it at a model running on hardware you own, or at a hosted API.
Provisioning the server
Do this in order. The reason to create the unprivileged user before hardening SSH is that you can still recover through the Hetzner web console if you lock yourself out β but it is much less painful not to.
# On your laptop β generate a key if you do not already have one: ssh-keygen -t ed25519 -C "openclaw-vps" # Paste the PUBLIC key (~/.ssh/id_ed25519.pub) into Hetzner Cloud # when creating the server. Never upload the private key anywhere.
Password login on a public-facing server is attacked within minutes of the IP going live. Use a key from the start; the private half never leaves your laptop.
ssh root@<server-ip> apt update && apt full-upgrade -y apt install -y curl git ufw fail2ban unattended-upgrades dpkg-reconfigure --priority=low unattended-upgrades
unattended-upgrades matters more on a VPS than at home: this machine is exposed to the internet permanently and you will not be watching it.
adduser --disabled-password --gecos "" deploy usermod -aG sudo deploy rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy/ # verify you can log in as deploy in a SECOND terminal # before you close this one: # ssh deploy@<server-ip>
Open a second terminal and confirm the new user can log in before you close the root session. This is the step people skip and then regret.
curl -fsSL https://openclaw.ai/install.sh | bash openclaw --version openclaw doctor
Install as the deploy user, not root. The service does not need root and giving it root turns a single vulnerability into a full compromise.
Hardening before you expose anything
A self-hosted agent has credentials for your accounts and often shell access to other machines. It is a higher-value target than a typical hobby VPS, so treat this section as mandatory rather than optional.
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config sudo sshd -t && sudo systemctl reload ssh
sshd -t validates the config before you reload. Skipping that check is the classic way to lock yourself out of a remote box.
sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw enable sudo ufw status verbose # Note what is NOT here: port 18789 is never opened.
The important line is the one that is absent: the gateway port is never opened to the internet. An agent endpoint reachable from the public internet is a remote code execution surface with your credentials behind it.
# Bind the gateway to loopback only. openclaw config set gateway.bind 127.0.0.1 openclaw config set gateway.port 18789 # Reach it from your laptop over an SSH tunnel instead: # ssh -N -L 18789:127.0.0.1:18789 deploy@<server-ip> # then open http://127.0.0.1:18789 locally.
An SSH tunnel gives you the web UI on your laptop with no exposed port and no extra service to secure. If you need a public HTTPS endpoint for webhooks, use a tunnel with authentication rather than opening the port.
sudo systemctl enable --now fail2ban sudo fail2ban-client status sshd # and confirm the firewall survived a reboot: sudo reboot # ... then: sudo ufw status
Rules that only exist until the next restart are not rules. Reboot and re-check before you consider the machine done.
When a VPS is the wrong answer
- βYou want a local model to feel fast. Without a GPU it will not, at any plan size.
- βThe workload is sensitive and you are not comfortable with the data living on someone else's hardware.
- βYou already own a machine that is on anyway. A Mac Mini or a Pi at home costs nothing extra in electricity terms compared with a monthly bill.
- βYou need a GPU occasionally. Rent GPU hours for those jobs instead of paying monthly for a CPU box that cannot do them.