OpenClaw on Hetzner: The No-BS Setup Guide for $4/Month

16 min read

OpenClaw is the hottest open-source AI agent on the planet. Here's how I actually set it up on a Hetzner VPS, every gotcha I hit, and what the docs don't tell you.

Part of the AI Agents topic hub.

Table of Contents

Last week, all I kept hearing about was OpenClaw. My Discord was flooded with it. My Twitter timeline was drowning in lobster emojis. 164,000 GitHub stars. Two million website visitors in a single week. Peter Steinberger’s “weekend project” had become the fastest-growing open-source project in history.

So naturally, I had to try it.

Here’s the thing though — for a project with 164K stars and wall-to-wall media coverage, the actual setup experience is… rough. The docs assume you know things you don’t. The config validation is strict but the error messages are vague. And if you’re not careful with permissions, you’re basically handing your server keys to an AI that can modify its own system prompt.

I spent an evening getting OpenClaw running on a Hetzner VPS, and I documented every single step, mistake, and gotcha along the way. By the end of this guide, you’ll have a fully working OpenClaw instance running 24/7 on a $4/month server, connected to Discord, with proper security hardening. No Docker required.

Let’s dive in.

What is OpenClaw (The 60 Second Version)

If you’ve been living under a rock: OpenClaw is a free, open-source AI agent that runs on your own machine. You talk to it through messaging platforms — WhatsApp, Telegram, Discord, Slack, iMessage — and it can actually do things on your behalf. Browse the web, manage files, run code, automate tasks. Think of it as your own personal AI agent that lives on a server and responds to your chat messages.

It’s built in TypeScript by Peter Steinberger, the guy who founded PSPDFKit (which sold for ~$100M). The project went through three name changes in two weeks — Clawdbot, then Moltbot (after Anthropic sent a trademark complaint), then finally OpenClaw. The lobster theme stuck throughout. Don’t ask me why.

The architecture is actually pretty elegant. There’s a WebSocket gateway that handles all your messaging channels, a “brain” that routes your messages to an LLM (Claude, GPT, DeepSeek, whatever), and an optional Docker sandbox for code execution. It stores conversation history locally in JSONL files and uses Markdown documents for persistent memory.

What makes it interesting compared to just chatting with Claude or ChatGPT directly is that OpenClaw has agency. It can run shell commands, control a browser, hit APIs, and chain actions together. And since it’s self-hosted, your data stays on your machine.

Why a VPS (And Why Hetzner)

You could run OpenClaw on your laptop. But here’s the problem: OpenClaw needs to be running 24/7 to respond to messages. Your laptop sleeping means your bot goes offline. Your cat walking across your keyboard means your bot goes offline. You get the idea.

A VPS solves this. It’s always on, it has a stable IP, and it costs less than your morning coffee.

I picked Hetzner for a few reasons:

ProviderCheapest OptionWhy / Why Not
Hetzner$3.99/mo (CAX11)Best price-to-performance. Great API for automation. My pick.
DigitalOcean$6/moHas a pre-built OpenClaw marketplace image if you want easy mode
Vultr$5/moSolid, more global regions than Hetzner
Oracle CloudFree4 ARM cores + 24GB RAM on free tier. Hard to beat $0, but signup is finicky
AWS Lightsail$5/moFine if you’re already in the AWS ecosystem

Hetzner’s ARM servers (the CAX line) are the sweet spot. You get 2 cores and 4GB RAM for under four bucks a month. OpenClaw is a Node.js process — it doesn’t need beefy hardware.

Prerequisites

Before we start, you’ll need:

  • A Hetzner Cloud account — sign up at console.hetzner.cloud
  • An Anthropic API key — from console.anthropic.com. OpenClaw supports other LLMs, but Claude Sonnet 4.5 is the recommended model and what I use.
  • A Discord bot token — create an app at discord.com/developers, add a Bot, and enable Message Content Intent under Privileged Gateway Intents. (Telegram is even easier to set up if you prefer — just talk to @BotFather.)
  • The Hetzner CLI — install with brew install hcloud on Mac

If you don’t have the Hetzner CLI yet:

brew install hcloud

Then authenticate it with your Hetzner API token (create one in your Hetzner project under Security > API Tokens with Read & Write permissions):

hcloud context create openclaw
# Paste your API token when prompted

Step 1: Generate an SSH Key

If you don’t already have an SSH key (check with ls ~/.ssh/id_*.pub), generate one:

ssh-keygen -t ed25519 -C "openclaw-hetzner" -f ~/.ssh/id_ed25519 -N ""

Upload it to Hetzner:

hcloud ssh-key create --name openclaw-key --public-key-from-file ~/.ssh/id_ed25519.pub

Step 2: Provision the Server

Here’s where I hit my first gotcha. The Hetzner docs and blog posts everywhere reference server types like cx22. That type doesn’t exist anymore. The naming scheme changed. Here’s what’s actually available:

TypeArchCoresRAMDiskPrice
cax11ARM24 GB40 GB$3.99/mo
cpx11x8622 GB40 GB~$3.49/mo
cx23x8624 GB40 GB~$4.49/mo

The CAX11 is the move. ARM is cheaper and Node.js runs great on it.

Second gotcha: ARM servers (CAX line) are only available in EU regions — Falkenstein (fsn1), Nuremberg (nbg1), and Helsinki (hel1). No US East. For an AI chatbot, latency to the server doesn’t matter — the LLM API call is the bottleneck, not the 100ms of transatlantic ping — so EU is fine.

Third gotcha: Not all EU locations are always available. I tried Falkenstein first and got a resource_unavailable error. Nuremberg worked fine.

hcloud server create \
  --name openclaw \
  --type cax11 \
  --image ubuntu-24.04 \
  --location nbg1 \
  --ssh-key openclaw-key

You’ll get back an IPv4 address. Note it down — that’s your server.

Server 120223561 created
IPv4: 46.224.234.146

Verify it’s working:

ssh root@YOUR_IP "uname -a && free -h"
Linux openclaw 6.8.0-90-generic aarch64 GNU/Linux
               total        used        free
Mem:           3.7Gi       329Mi       3.4Gi

3.7GB of RAM, Ubuntu 24.04, ARM64. We’re cooking.

Step 3: Install Node.js and OpenClaw

OpenClaw requires Node.js 22 or higher. SSH in and install it:

ssh root@YOUR_IP

# Install Node.js 22
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs

# Verify
node --version  # v22.22.0
npm --version   # 10.9.4

Now install OpenClaw globally:

npm install -g openclaw@latest
openclaw --version  # 2026.2.3-1

That’s it. 666 npm packages later (ominous, I know), OpenClaw is installed. You’ll see some deprecation warnings about tar and glob — ignore them.

Step 4: Set Up the Firewall

Before we configure anything sensitive, lock down the server:

ufw allow 22/tcp      # SSH
ufw allow 18789/tcp   # OpenClaw gateway
ufw --force enable
ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
18789/tcp                  ALLOW       Anywhere

Only SSH and the OpenClaw gateway port are open. Everything else is blocked.

Step 5: Configure OpenClaw

This is where things get interesting. OpenClaw uses a JSON config file at ~/.openclaw/openclaw.json. The docs say it supports JSON5 (comments, trailing commas), and it validates strictly with Zod schemas — unknown keys or wrong types will prevent the gateway from starting.

Create the directory structure:

mkdir -p ~/.openclaw/workspace

Now create the config. Here’s the minimum viable config that actually works:

{
  "agents": {
    "defaults": {
      "workspace": "~/.openclaw/workspace",
      "model": {
        "primary": "anthropic/claude-sonnet-4-5"
      }
    },
    "list": [
      {
        "id": "main",
        "default": true
      }
    ]
  },

  "gateway": {
    "mode": "local",
    "port": 18789
  },

  "web": {
    "enabled": true
  },

  "env": {
    "ANTHROPIC_API_KEY": "sk-ant-your-key-here",
    "DISCORD_BOT_TOKEN": "your-discord-bot-token-here"
  },

  "channels": {
    "discord": {
      "enabled": true,
      "token": "your-discord-bot-token-here",
      "dm": {
        "enabled": true,
        "policy": "pairing"
      }
    }
  },

  "tools": {
    "profile": "full"
  }
}

Replace the placeholder values with your actual API key and Discord bot token, then save it to ~/.openclaw/openclaw.json.

Config Gotchas I Hit

Let me save you some pain. Here are the config fields that tripped me up:

gateway.mode is required. Without "mode": "local", the gateway refuses to start with: Gateway start blocked: set gateway.mode=local (current: unset). The docs don’t make this obvious.

session.reset.mode: "off" is not valid. I tried adding "session": {"reset": {"mode": "off"}} and got Invalid input. Just leave the session config out entirely — the defaults are fine.

gateway.bind doesn’t accept IP addresses. I tried "bind": "0.0.0.0" to expose the Web UI and got Invalid input. The gateway binds to loopback by default. We’ll use an SSH tunnel for the Web UI instead (which is more secure anyway).

The env block inlines your secrets. When you run openclaw doctor --fix, it resolves ${VAR} references and writes the actual values into the config file. So your API keys end up in plaintext in the JSON. Lock down the file permissions: chmod 600 ~/.openclaw/openclaw.json.

Step 6: Run the Doctor

OpenClaw has a built-in diagnostic tool. Run it to validate your config and fix any issues:

openclaw doctor --fix

It’ll flag things like:

  • Missing directories (~/.openclaw/agents/main/sessions, ~/.openclaw/credentials)
  • Loose file permissions
  • Discord being “configured but not enabled”
  • Missing gateway auth tokens

The doctor creates the missing directories and updates your config. After it runs, harden permissions:

chmod 700 ~/.openclaw
chmod 600 ~/.openclaw/openclaw.json

Step 7: Create a systemd Service

You don’t want to run OpenClaw in a terminal session that dies when you disconnect. Create a systemd service so it starts on boot and restarts on crashes:

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

[Service]
Type=simple
User=root
ExecStart=/usr/bin/openclaw gateway --port 18789
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable openclaw
systemctl start openclaw

Check the logs:

journalctl -u openclaw --no-pager -n 20

If everything worked, you’ll see something like:

[gateway] agent model: anthropic/claude-sonnet-4-5
[gateway] listening on ws://127.0.0.1:18789 (PID 3983)
[browser/service] Browser control service ready (profiles=2)
[discord] starting provider (@openclaw)
[discord] logged in to discord as 1469572782429044970

That last line is the money shot. Your bot is live on Discord.

Step 8: Invite the Bot and Pair Your Account

Your bot needs to be in a Discord server before you can talk to it. Generate an invite link:

  1. Go to discord.com/developers/applications
  2. Select your app > OAuth2 > URL Generator
  3. Check bot scope
  4. Check Send Messages, Read Message History, Read Messages/View Channels permissions
  5. Copy the URL and open it in your browser to invite the bot to your server

Now DM the bot. You’ll get this message:

OpenClaw: access not configured.

Your Discord user id: 541442279886422046
Pairing code: 3FPMYNZS

Ask the bot owner to approve with:
openclaw pairing approve discord <code>

Since you’re the owner, SSH into the server and approve yourself:

openclaw pairing approve discord 3FPMYNZS
Approved discord sender 541442279886422046.

Send the bot another message. It should respond now. You’ve got a personal AI agent running 24/7 on a $4/month server. Pretty sweet.

Step 9: Access the Web UI

OpenClaw comes with a browser-based dashboard for managing agents, sessions, skills, and cron jobs. Since the gateway binds to localhost, you access it through an SSH tunnel:

ssh -L 18789:127.0.0.1:18789 -N root@YOUR_IP

This forwards your local port 18789 to the server’s localhost:18789. Open your browser to:

http://localhost:18789

If you get a “gateway token missing” error, the doctor added an auth token to your config. Find it with:

ssh root@YOUR_IP 'grep -A2 auth ~/.openclaw/openclaw.json'

Then access the dashboard at:

http://localhost:18789/?token=YOUR_TOKEN_HERE

The Web UI gives you a chat interface, session management, and configuration controls — all in the browser. It’s nice for quick interactions when you don’t want to go through Discord.

Cost Breakdown

Here’s what this setup actually costs:

ItemCost
Hetzner CAX11 server$3.99/mo
OpenClaw softwareFree (MIT license)
Anthropic API (light use)$10-30/mo
Anthropic API (moderate use)$30-70/mo
Discord botFree
Total (light use)~$14-34/mo

The server is the cheapest part. Your API costs depend entirely on how chatty you are with the bot and how complex your tasks are. If you want to save on API costs, OpenClaw supports local models through Ollama — but you’ll need beefier hardware.

Security: The Elephant in the Room

I’d be irresponsible not to address this. OpenClaw has been called a “security nightmare” by Cisco, and The Register, CrowdStrike, and Trend Micro have all published reports flagging serious concerns.

The issues are real:

  • One-click RCE vulnerability — a crafted malicious link could trigger remote code execution because the WebSocket server wasn’t validating origin headers. (Fixed in recent versions, but still.)
  • Broad permissions — with "tools": {"profile": "full"}, OpenClaw can access your file system, run shell commands, and browse the web. On a VPS this is somewhat contained. On your personal laptop, it’s terrifying.
  • Self-modification — agents can modify their own system prompt and add new communication channels without human confirmation.
  • Skill supply chain — 26% of community-contributed skills have at least one vulnerability.

What I Did to Mitigate

  1. Dedicated VPS — OpenClaw runs on its own server with nothing else on it. If it gets compromised, the blast radius is limited.
  2. Firewall — Only SSH and the gateway port are open.
  3. SSH tunnel for Web UI — The dashboard isn’t exposed to the internet.
  4. File permissions — Config locked to 600, directory to 700.
  5. Pairing required — DM policy is set to "pairing", so only approved users can interact with the bot.

Is it bulletproof? No. But it’s a lot better than running it on your personal machine with full disk access.

The Full Gotcha List

For the impatient, here’s every issue I hit in one place:

  1. cx22 doesn’t exist — Hetzner renamed their server types. Use cax11 for ARM or cx23 for x86.
  2. ARM servers are EU only — No US regions for CAX line. Doesn’t matter for a chatbot.
  3. Some EU locations are unavailablefsn1 returned resource_unavailable. Try nbg1 or hel1.
  4. gateway.mode: "local" is required — Not set by default, but the gateway won’t start without it.
  5. session.reset.mode: "off" is invalid — Just omit the session config entirely.
  6. gateway.bind: "0.0.0.0" is invalid — Use an SSH tunnel instead.
  7. openclaw doctor --fix inlines your secrets — Your API keys get written in plaintext to the config file. Lock down permissions.
  8. Discord says “configured, not enabled” — Run openclaw doctor --fix to activate it.
  9. Web UI needs auth token in URL — Pass ?token=YOUR_TOKEN or paste it in the Control UI settings.
  10. Discord pairing is required — You have to approve your own Discord user ID before the bot responds.

What I’m Building Next

This was step one. I’ve got two bigger projects in the works:

An automated setup service — Enter your details, pay a one-time fee, and I spin up a fully configured OpenClaw instance on a VPS for you. No SSH, no config files, no gotchas. Just a working bot in your Discord or Telegram.

A consumer-friendly version — Think Claude Cowork meets OpenClaw. The same always-on agent capabilities, but wrapped in a UI that doesn’t require a terminal. The agent-for-everyone future that OpenClaw hints at but doesn’t quite deliver yet.

If either of those sounds interesting, subscribe below and I’ll share updates as I build.

Wrapping Up

OpenClaw is genuinely impressive. A self-hosted AI agent with 50+ integrations that you can talk to through Discord? For four bucks a month? That’s wild.

But the setup experience tells you this is still an early, developer-focused project. The config validation is strict without being helpful. The docs assume context you don’t have. And the security model requires real expertise to get right.

If you’re technical and willing to spend an evening on it, the result is worth it. You end up with an always-on AI assistant that can do things ChatGPT and Claude’s web interfaces simply can’t.

Clone it, set it up, break it, fix it. And if you build something cool with it, let me know.

Related Posts

Read The Ultimate Guide to Claude Cowork: Create Your Personal AI Assistant
Hero image for The Ultimate Guide to Claude Cowork: Create Your Personal AI Assistant
guide claude ai-agents

The Ultimate Guide to Claude Cowork: Create Your Personal AI Assistant

Learn how to turn Claude Cowork into a personal AI assistant that organizes your files, drafts documents, schedules recurring tasks, and connects to your tools. The complete guide, no coding required.

34 min
Read Claude Managed Agents: Anthropic Now Runs Your Agents For You
Hero image for Claude Managed Agents: Anthropic Now Runs Your Agents For You
guide ai-agents claude

Claude Managed Agents: Anthropic Now Runs Your Agents For You

Anthropic just launched Managed Agents, letting you spin up autonomous Claude agents in their cloud with containers, tools, and multi-agent orchestration built in. Here's how it works and how to get started.

13 min
Read The Anatomy of Claude Code And How To Build Agent Harnesses
Hero image for The Anatomy of Claude Code And How To Build Agent Harnesses
guide claude ai-agents

The Anatomy of Claude Code And How To Build Agent Harnesses

The source code for Claude Code leaked. In this post, we explore how it actually works, from the moment you type a message to the moment it delivers working code.

38 min