Deploy an AI Agent on Hetzner VPS: Full 2026 Walkthrough
Step-by-step Hetzner VPS setup for a self-hosted AI agent in 2026: plan sizing, firewall hardening, Docker Compose, Telegram, and what breaks at 3 AM.

Why Hetzner Keeps Coming Up for Self-Hosted Agents
If you have spent any time in the self-hosting corner of dev.to, Medium, or the indie-AI Telegram groups, you have noticed the same pattern: when someone asks where to run an always-on AI agent for less than the price of two coffees, the top answer is Hetzner Cloud. The community keeps landing there for two reasons that have been stable for years: real CPU performance per euro, and a clean Cloud Firewall you can configure before the server even boots.
This walkthrough is for the reader who has decided to self-host an AI agent (Hermes Agent, OpenClaw, an n8n setup with an LLM node, or anything else that calls a model API from a long-lived server) and wants to do it on Hetzner without skipping the parts that matter at 3 AM. Sizing, hardening, Docker Compose, a Telegram channel test, and the honest list of things that will go wrong eventually.
If you are still deciding which cheap VPS to use, our cheap VPS comparison covers the wider field. This post assumes you have picked Hetzner.
Step 1: Pick the Right Plan
Hetzner Cloud as of mid-2026 splits its shared-vCPU plans into three lines:
- CX (Intel) - older Intel shared vCPUs, being phased out in some regions
- CPX (AMD EPYC) - the current x86 default, fastest single-thread
- CAX (ARM Ampere) - the cheapest line, very strong perf-per-euro
For an API-driven AI agent (one that calls OpenAI, Anthropic, OpenRouter, or your own Ollama box and orchestrates tool calls locally) the plan you want is the smallest one in any of these lines:
| Plan | vCPU | RAM | NVMe | EU price | Notes | |---|---|---|---|---|---| | CAX11 (ARM) | 2 | 4 GB | 40 GB | ~€3.79/mo | Cheapest viable option | | CX22 (Intel) | 2 | 4 GB | 40 GB | ~€3.79/mo | Being deprecated in some regions | | CPX11 (AMD) | 2 | 2 GB | 40 GB | ~€4.59/mo | Best single-thread x86 | | CPX21 (AMD) | 3 | 4 GB | 80 GB | ~€7.55/mo | Headroom for second agent or browser tools |
US-region prices are slightly higher (roughly $4.59-$4.99 for the equivalent CX22 spec). Hetzner adjusted prices on June 15, 2026 - new orders use the new rate, existing servers keep the old rate until you rescale.
Recommendation: start with CAX11 or CX22. Two vCPU and 4 GB of RAM is enough for a single agent, a Telegram gateway, a small reverse proxy, and a Docker daemon, with headroom for the occasional headless-browser task. If you plan to run multiple agents, scrape pages with Playwright, or batch-run skills overnight, jump to CPX21.
If your agent runtime does not yet ship an ARM image, stay on CX22 or CPX11. Most popular runtimes (Hermes Agent, OpenClaw, n8n) do ship linux/arm64 images today, so the CAX line is usually fair game.
Step 2: Provision and Lock Down the Server Before SSH
This is the step that gets skipped most often and bites later. Hetzner gives you two firewalls (the edge-level Cloud Firewall and the host-level UFW). Use both. The Cloud Firewall is the one to configure before the server boots so that it never accepts a single packet on a port you do not intend to open.
In the Hetzner Console, create a Cloud Firewall with these inbound rules:
- TCP 22 from your IP only (or from a small CIDR if you have a fixed office range)
- TCP 80 from
0.0.0.0/0, ::/0(only if you will run a reverse proxy on this box) - TCP 443 from
0.0.0.0/0, ::/0(only if you need HTTPS for webhooks or a web UI) - ICMP from
0.0.0.0/0, ::/0(sopingworks for monitoring)
Outbound: leave the default "allow all" - the agent needs to reach the model API.
Now create the server, attach the firewall, and choose Ubuntu 24.04 LTS. In the SSH-keys panel, add the public key from your laptop. Do not allow password login.

Once the server is up, SSH in as root and immediately do four things:
# 1. Patch
apt update && apt upgrade -y && apt install -y ufw fail2ban unattended-upgrades
# 2. Create a non-root user
adduser --disabled-password --gecos "" agent
usermod -aG sudo agent
mkdir -p /home/agent/.ssh && cp ~/.ssh/authorized_keys /home/agent/.ssh/
chown -R agent:agent /home/agent/.ssh && chmod 600 /home/agent/.ssh/authorized_keys
# 3. Lock down SSH
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart ssh
# 4. Host firewall (UFW), redundant with Cloud Firewall but a useful safety net
ufw default deny incoming && ufw default allow outgoing
ufw allow OpenSSH && ufw allow 80/tcp && ufw allow 443/tcp
ufw --force enable
Then enable unattended security upgrades and fail2ban with sensible defaults:
dpkg-reconfigure -plow unattended-upgrades # answer Yes
systemctl enable --now fail2ban
Fail2ban will, by default, ban IPs after 5 failed SSH attempts within 10 minutes. The Cloud Firewall already drops most of those at the edge, but fail2ban catches anything that slips through (a coworker, a misconfigured CI runner, you).
Log out of root, log back in as agent, and continue from there.
Step 3: Install Docker
Docker is the cleanest way to run an AI agent on a VPS in 2026. The agent stays isolated, dependencies do not pollute the host, and updates are one pull && up away.
# As the agent user, with sudo
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker agent
newgrp docker
docker run --rm hello-world
If hello-world prints, Docker is good to go.
Step 4: Deploy the Agent with Docker Compose
Create ~/agent/docker-compose.yml on the server. The example below is for Hermes Agent, but the structure is identical for OpenClaw, Open WebUI + an LLM provider, or any other containerized agent runtime.
services:
agent:
image: ghcr.io/your-runtime/agent:latest
container_name: agent
restart: unless-stopped
env_file: .env
volumes:
- ./data:/data
- ./skills:/skills
- ./memory:/memory
ports:
- "127.0.0.1:8080:8080" # web UI bound to localhost only
Then create ~/agent/.env:
# Model provider (BYOK - bring your own key)
OPENAI_API_KEY=sk-...
# Or any of:
# ANTHROPIC_API_KEY=...
# OPENROUTER_API_KEY=...
# Messaging gateway
TELEGRAM_BOT_TOKEN=...
TELEGRAM_ALLOWED_USERS=12345678 # your Telegram user ID
# Persistence
DATA_DIR=/data
MEMORY_DIR=/memory
chmod 600 .env so other users on the box cannot read your keys, then bring it up:
docker compose up -d
docker compose logs -f agent
The restart: unless-stopped policy is what keeps the agent alive across reboots. If you prefer a native install instead of Docker, the equivalent is a systemd unit with Restart=always and WantedBy=multi-user.target.
Step 5: Wire Up Telegram and Test
If you went with Telegram as your messaging surface (most self-hosters do, because the Bot API is free and instant), the test loop is short:
- Talk to @BotFather on Telegram, run
/newbot, save the token into.env. - Talk to @userinfobot to get your numeric Telegram user ID, put it in
TELEGRAM_ALLOWED_USERS. docker compose restart agent.- Open your new bot in Telegram and send "hello".
You should see a response within a few seconds. If you do not, docker compose logs -f agent will usually point straight at the problem (missing token, wrong allowed-user ID, model provider returning 401).
For a much deeper walkthrough of the Telegram side (groups, topics, voice mode, troubleshooting), see how to build an AI agent on Telegram.

Step 6: Backups and Monitoring (the Part Everyone Skips)
Two cheap things that pay for themselves the first time something breaks:
- Hetzner snapshots: in the Console, enable a daily snapshot of the server. Roughly €0.012/GB/month, around €0.50/month for a 40 GB disk. Tag one "before-update" before any
docker compose pull. - An uptime ping: free with BetterStack or UptimeRobot. Have it hit
https://your-domain/health(or just a TCP check) every 5 minutes. The first time the Telegram gateway drops connection at 3 AM, you will know before lunch instead of at lunch.
For the agent's own state (memory files, skills, conversation history), put a one-line cron job that tars the mounted volume into /var/backups/agent-$(date +%F).tar.gz and rotates older copies. Rsync that off-box weekly to a second cheap VPS, an S3-compatible bucket, or your laptop.
Step 7: Updates
Once a week, with the snapshot already taken:
cd ~/agent
docker compose pull
docker compose up -d
docker image prune -f
The whole thing usually takes under a minute. If the new image breaks, restore the snapshot from the Hetzner Console - the only state you lose is the conversations between snapshot and now, which sit in the agent's memory volume.
What Breaks Eventually
A short, honest list:
- Telegram long-polling drops during long network blips. Most runtimes auto-reconnect, but if yours does not, the uptime ping is what catches it.
docker compose pullships a breaking config change. Pin the image tag to a specific version in production rather than:latest.- The model provider rate-limits you and the agent stops responding without an obvious error. Always log the provider's HTTP status, and prefer providers with usage dashboards.
- A disk fills up because a skill writes to
/tmpwithout rotation.du -sh /*anddocker system dfshould be in your debugging muscle memory. - You forget the firewall rule when you add a second service. Both firewalls (Cloud + UFW) need the new port, or you spend 20 minutes debugging "connection refused" from the right address.
None of these are Hetzner-specific. They are the tax on running anything yourself.
When the VPS Math Stops Working
If you are reading this and the steps above sound interesting - great, this is exactly the workflow Hetzner is good for. Cheap, fast, transparent.
If they sound like a tax on a weekend, the comparison shifts. Managed hosting trades €4/month and a Sunday afternoon for a setup that already includes the Telegram gateway, BYOK to your provider, persistent memory volumes, snapshots, and "it just stays up". Our hosting vs self-hosting guide walks through the full math, including what your time is worth.
Get started with Hermify if you want the managed path - an agent on production infrastructure in under 30 minutes, no Cloud Firewall to configure and no fail2ban to tune. If you would rather do it yourself on Hetzner, this guide should get you there.
Sources
- Hetzner Cloud Pricing 2026 - bestusavps.com
- Hetzner Price Adjustment - Hetzner Docs
- Hetzner Data Center Locations - Hetzner Docs
- Basic Cloud Config - Hetzner Community
- Running an AI Agent on a VPS: Security-First Setup - Medium / Tim Daniel Walter
- How to Deploy an AI Agent to Production - Paxrel
- Running AI Coding Agents on Hetzner - Pere Villega
Run Your Own Hermes Agent
Bring your API key, connect Telegram, and get a self-improving AI agent live in 60 seconds.
Get Started