If you landed here you probably Googled “how to set up OpenClaw on Hetzner cloud server.” I just did the install for a side-project that needs EU-only data residency, took notes, and cleaned them up. Everything below was verified on Hetzner CX22 running Ubuntu 24.04 LTS and OpenClaw v1.7.3 (the current npm dist as of 2024-06-01).

Why Hetzner + OpenClaw makes sense

For personal agents or small SaaS features you need three things: predictable latency, a public IPv4, and a TCO that doesn’t nuke your credit card. Hetzner’s entry plan (CX22, 2 vCPU / 4 GB RAM, €4.49 monthly) is enough to keep one OpenClaw instance responsive to Slack, WhatsApp, a browser tool, and a few scheduled tasks. Add €1 for a floating IP and you’re still cheaper than one month of coffee.

On the compliance side, Hetzner keeps everything in Germany or Finland. If you work with EU customer data and need to avoid transatlantic drift for GDPR Article 44, you’re safe as long as you don’t wire the agent to US-hosted tools (that’s on you).

Pick the right server and image

Minimum spec

  • CX22 or better. Node 22 JIT likes at least two cores.
  • 30 GB disk is the default; fine unless you’re dumping logs or using browser caching heavily.
  • Ubuntu 24.04 LTS (noble). 22.04 works too, but 24.04 ships a newer systemd that fixes lingering slice issues.

Provision in the console

  1. Log in to console.hetzner.cloud. Create a new project if needed.
  2. Select Servers ▶️ Add Server.
  3. Choose a region close to your users (fsn1 = Falkenstein, nbg1 = Nuremberg, hel1 = Helsinki).
  4. Image: ubuntu-24.04
  5. Type: CX22 or bigger.
  6. SSH Key: import your public key so root login is key-only from day one.
  7. Enable the free Hetzner firewall for 22/tcp (SSH) and leave port 80/443 closed for now—we’ll punch exact holes later.
  8. Click Create & Buy Now. Wait 30 seconds; you’ll get an IPv4.

Initial Ubuntu hardening (don’t skip)

Hetzner images come reasonably clean, but two minutes here saves a weekend later.

Create a non-root user and lock down SSH

ssh root@203.0.113.42 # use your IP adduser claw usermod -aG sudo claw mkdir -p /home/claw/.ssh cp /root/.ssh/authorized_keys /home/claw/.ssh/ chown -R claw:claw /home/claw/.ssh chmod 700 /home/claw/.ssh && chmod 600 /home/claw/.ssh/authorized_keys

Edit /etc/ssh/sshd_config:

PermitRootLogin no PasswordAuthentication no systemctl restart sshd exit ssh claw@203.0.113.42 # verify you can log in

Enable ufw and allow only what OpenClaw needs

sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp # SSH sudo ufw allow 443/tcp # HTTPS for the gateway sudo ufw enable sudo ufw status verbose

Don’t expose the OpenClaw control port (default 3000) to the public net. We’ll reverse-proxy it.

Install Node 22 and OpenClaw

Why not apt?

Ubuntu’s repo sits at Node v18. We need 22. Using nvm or asdf keeps upgrades frictionless.

# logged in as claw curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 22 nvm alias default 22 node -v # v22.x.y

Install OpenClaw globally

npm install -g openclaw@1.7.3 # latest at writing openclaw --version # should print 1.7.3

OpenClaw drops two executables:

  • openclaw gateway – the Web UI + HTTP API
  • openclaw daemon – background tasks, scheduled runs, memory jobs

Create a project directory

mkdir -p ~/agents/mybot && cd $_ openclaw init # interactive prompts: name, default model, etc.

The wizard writes openclaw.config.json and a memory/ SQLite db.

Run gateway and daemon under systemd

PM2 or Docker would also work, but systemd keeps logs in journalctl and restarts on failure. Two units: one for the gateway, one for the daemon.

/etc/systemd/system/openclaw-gateway.service

[Unit] Description=OpenClaw Gateway After=network.target [Service] Type=simple User=claw WorkingDirectory=/home/claw/agents/mybot Environment="NODE_ENV=production" ExecStart=/home/claw/.nvm/versions/node/v22.5.0/bin/openclaw gateway --port 3000 Restart=on-failure [Install] WantedBy=multi-user.target

/etc/systemd/system/openclaw-daemon.service

[Unit] Description=OpenClaw Daemon After=network.target [Service] Type=simple User=claw WorkingDirectory=/home/claw/agents/mybot Environment="NODE_ENV=production" ExecStart=/home/claw/.nvm/versions/node/v22.5.0/bin/openclaw daemon Restart=on-failure [Install] WantedBy=multi-user.target sudo systemctl daemon-reload sudo systemctl enable --now openclaw-gateway openclaw-daemon sudo systemctl status openclaw-gateway -n 20

Expose the gateway via HTTPS with Caddy

You can use nginx + certbot if you prefer. I switched to Caddy because the config is one file and it renews Let’s Encrypt automatically.

Install Caddy from official repo

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy.asc curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy.list sudo apt update sudo apt install caddy -y

Edit /etc/caddy/Caddyfile

openclaw.example.eu { reverse_proxy localhost:3000 encode zstd gzip log { output file /var/log/caddy/openclaw.access.log } } sudo systemctl reload caddy

Point your DNS A record to the server’s IP. Caddy will grab a cert the first time traffic arrives. Test:

curl -I https://openclaw.example.eu

Connect remote channels (Telegram example)

The hosted ClawCloud UI makes OAuth flows painless, but self-hosting means manual API keys. Telegram is the fastest to validate.

  1. Open my.telegram.orgAPI Development Tools.
  2. Create an app. Note api_id and api_hash.
  3. In the OpenClaw UI (https://openclaw.example.eu) go to Integrations ▶️ Telegram and paste the creds.
  4. Start a chat with @BotFather, create a bot, grab the token, and drop it in.
  5. Send /ping to your bot; you should get Pong back if both gateway and daemon are talking.

Slack, Discord, WhatsApp via WhatsApp Web all follow similar patterns; the docs live in /docs/integrations inside the repo.

EU data residency and GDPR notes

  • Server location: choose fsn1 or nbg1 for Germany, hel1 for Finland (also EEA).
  • Hetzner’s DPA meets GDPR Article 28. Sign it in the console under Security ▶️ Data Processing Agreement.
  • OpenClaw’s default memory backend is SQLite on local disk—no data leaves the VM unless you integrate cloud tools.
  • If you wire in OpenAI or Anthropic you’re again exporting data; switch to ollama or localai if you need full sovereignty.

Cost snapshot

ItemMonthly €
CX224.49
Floating IP (optional)1.00
Backups (20% toggle)0.90
Total6.39

That’s still half a DigitalOcean droplet while staying schengen-compliant.

Atomic backup and update routine

OpenClaw updates weekly. Node sometimes breaks ABI. Keep a repeatable script.

# weekly cronjob as root (/etc/cron.weekly/openclaw-upgrade) #!/bin/bash set -euo pipefail systemctl stop openclaw-gateway openclaw-daemon su - claw -c "nvm install 22 && npm i -g openclaw@latest" systemctl start openclaw-gateway openclaw-daemon journalctl -u openclaw-gateway -n 20 --no-pager

For backups, enable Hetzner snapshots or rsync ~/agents/ to an object store. The SQLite file is usually under 50 MB.

Takeaway & next steps

You now have an EU-hosted OpenClaw instance reachable at https://openclaw.example.eu, auto-restarting on boot, and firewalled to the exact ports you need. Next up: wire the agent to Composio and automate your calendar, or add Ollama for on-device models so nothing ever leaves the Hetzner DC. Either way, you’ve got the base layer ready—spend your time on prompts, not ops.