The problem: deploying OpenClaw (the open-source AI agent framework) is annoying. Docker setup, Nginx config, SSL, firewall rules, Playwright browser installation for web tools, messenger bridge configuration. If you know what you're doing, it probably takes an hour. I got it down to 30-60 seconds.
*The provisioning trick: prewarmed VPS*
Snapshot-based provisioning alone gets you to about 3 minutes. Hetzner needs ~40s to create the VPS from a snapshot alone.
The thing that actually makes it fast is prewarming. I keep 1-2 idle VPS per tier sitting ready. They're already booted from the snapshot, Docker is running, everything is warm. When a customer clicks "Create Instance," I claim a prewarmed server, SSH in, upload configs, start containers. 30-60 seconds, done.
A background job monitors the pool and replenishes it. If empty, we fall back to fresh VPS creation (the 3-minute path). In practice, most signups hit a prewarmed server.
The snapshot has everything pre-baked: Docker with the OpenClaw image pre-pulled, Playwright Chromium browsers in a named volume, fail2ban, firewall rules. Nothing gets installed at deploy time.
*Routing: subdomains, Traefik, and HTTP auth*
Each instance gets its own subdomain (like `myagent.clawhosters.com`). Traefik reads route configs from Redis (domain → instance IP) and proxies to the right VPS. When an IP changes, Rails updates Redis and Traefik picks it up dynamically. It also handles optional HTTP basic auth per instance.
On each VPS, Nginx validates the Host header and returns 403 for direct IP access. The chain: internet → Traefik (routing + auth) → VPS Nginx (Host validation) → OpenClaw gateway.
*Firewall: locked to my server's IP*
Every instance gets a Hetzner Cloud firewall during provisioning. Ports are only open to my main server's IP, everything else is blocked. Customer VPS instances aren't directly reachable from the internet. Even if someone finds an instance IP, Hetzner drops the packets before they hit the VPS.
*The managed LLM proxy*
Each plan includes a managed LLM proxy. Instances talk to my proxy, and the proxy routes to whatever provider I've configured.
The security model: no API keys on the instances. Authentication is IP-based. Every VPS has a unique Hetzner IP and the firewall only allows traffic from my server. No tokens to leak, no credentials on customer machines.
Streaming was the hardest part. LLM responses come as SSE, and TCP chunks don't respect event boundaries. The proxy reassembles partial chunks on `\n\n` boundaries before forwarding. I keep only the last 4KB in a tail buffer to extract usage stats from the final `[DONE]` chunk without holding the entire response in memory.
Every request gets logged with tokens, cache hits, cost in microcents, provider, model. Rate limiting is per-instance, backed by Redis counters. I'd rather skip rate limits briefly than block the proxy. Customers can also bring their own API key (BYOK mode).
*Other bits:* Optional SSH access into containers for power users. ZeroTier sidecar for private network connectivity. Hot config reload via SIGUSR1 without container restarts.
*Stack:* Rails 8, PostgreSQL, Sidekiq, Hetzner Cloud API, Docker on instances. The entire platform runs as a namespace within a single Rails app. Built in about 2-3 weeks.
*Where it's at:* 180 customers, 46 running instances, 36 paying customers, 10 still in trial. 3 tiers from €19/mo to €59/mo.
I also just launched an affiliate program (15% recurring for 12 months): https://clawhosters.com/affiliate
Ask me anything about the provisioning architecture, the routing setup, or any of the Hetzner-specific gotchas. There were plenty.