claude-code·9 min read·
Claude Code on a Hetzner / UK VPS: the 2026 UK indie hacker setup
A VPS gives your Claude Code agents the one thing a laptop cannot: persistence through laptop close. Here is the GBP 3.30 a month setup on a Hetzner ARM box, the Cloudflare OAuth workaround that catches everyone, and the UK provider price comparison.

You have hit the wall every UK indie hacker hits about two months into building with Claude Code: your laptop sleeps, your scheduled tasks die, your morning brief does not fire because you closed the lid at 11pm. The fix is a small VPS, always on, costing less than a coffee a month. This post walks through the cheapest credible setup on a Hetzner ARM box, the OAuth blocker that catches everyone, and the security checklist that takes fifteen minutes to lock the thing down.
Why a VPS, why now
The case for a VPS is short: persistence. Three specific failure modes a VPS fixes.
- Laptop close. Scheduled
claude -pjobs do not fire when your laptop is asleep. systemd timers, cron, hooks - they all stop when the box stops. The Linux scheduling guide covers this in depth. - Webhooks. Any agent that needs to respond to a Slack mention or a GitHub webhook needs a public endpoint. Your laptop, behind NAT, on a domestic broadband connection, is not it. (Cloudflare Tunnel makes it workable but the listener still dies when the laptop sleeps.)
- SSH from the phone. A VPS on Tailscale is reachable from your phone in a cafe. Genuine "kick an agent from anywhere" only happens with the box up.
The other quiet win: a VPS gives you a clean, reproducible environment. Your laptop accumulates state, half-installed dev tooling, broken paths. A VPS is the same OS, the same packages, the same ~/.claude/ directory, every time you SSH in. Production agents like that.
The UK price comparison
The shape of the market in 2026, GBP per month, for a roughly equivalent spec (2 cores, 4GB RAM, 40-80GB SSD). All figures verified as of writing.
| Provider | Plan | Location | Spec | Monthly (GBP) | Notes |
|---|---|---|---|---|---|
| Hetzner | CAX11 (ARM) | Falkenstein / Helsinki | 2 vCPU ARM, 4GB, 40GB | ~3.30 | Cheapest credible option |
| Hetzner | CX22 (x86) | Falkenstein / Helsinki | 2 vCPU, 4GB, 40GB | ~3.80 | Use only if you need x86 |
| Hostinger | KVM 2 | Lithuania / UK | 2 vCPU, 8GB, 100GB | ~4.00 | Good middle option |
| Vultr | High Performance | London | 2 vCPU, 4GB, 80GB | ~4.50 | London POP, low latency |
| DigitalOcean | Basic Premium | London | 2 vCPU, 4GB, 80GB | ~5.50 | Familiar tooling tax |
| Mythic Beasts | VPS Small | UK | 2 vCPU, 4GB, 50GB | ~6.00 | UK data residency, B Corp |
| Bytemark | BigV | UK | 2 vCPU, 4GB, 50GB | ~8.00 | Veteran UK provider |
The honest analysis: Hetzner ARM at ~GBP 3.30 is the unbeatable price-performance leader. Claude Code runs fine on ARM in 2026 - the Node binary is built for arm64, the install script handles the architecture detection. The 20-30ms latency from Falkenstein to UK is invisible for an agent workload (where Anthropic API round-trips dominate anyway).
The case for paying more:
- Mythic Beasts if you need a UK-based provider for client work or data residency reasons. They are a B Corp, the tooling is solid, and the price premium is justified by the geography.
- Vultr London if you want a London POP and familiar dashboard tooling.
- DigitalOcean if you already live in their ecosystem and the marginal time savings are worth the extra pound or two.
For pure "I want a cheap reliable box to run my agents", Hetzner CAX11 is the answer.
The setup walkthrough
Ten minutes, end to end, from clicking "Create Server" to a working claude invocation.
1. Provision the box
Hetzner Cloud Console: create a CAX11 in Falkenstein, Ubuntu 24.04 LTS, add your SSH key during creation, no extra volumes needed for a basic setup. The box is ready in about 30 seconds. Note the public IPv4 address.
2. SSH in and update
ssh root@<your-ip>
apt update && apt upgrade -y
apt install -y curl ufw fail2ban
3. Create a non-root user
adduser tim
usermod -aG sudo tim
mkdir -p /home/tim/.ssh
cp ~/.ssh/authorized_keys /home/tim/.ssh/
chown -R tim:tim /home/tim/.ssh
chmod 700 /home/tim/.ssh
chmod 600 /home/tim/.ssh/authorized_keys
Log out and back in as the new user: ssh tim@<your-ip>. Confirm sudo -i works.
4. Install Node and Claude Code
Claude Code in 2026 ships as a Node CLI. Use the install script:
curl -fsSL https://claude.ai/install.sh | bash
The script detects ARM and installs the right binary. Confirm with claude --version.
5. Authenticate (this is where the Cloudflare issue bites)
claude login opens the OAuth flow. On Hetzner Cloud IPs, the Cloudflare JS challenge on Anthropic's OAuth endpoint blocks the token exchange. The symptom: the flow hangs, or you get a 403, or the browser redirect never completes. This is GitHub issue anthropics/claude-code #21678 and it has been confirmed by Anthropic.
The two workarounds, both clean:
Workaround A: copy credentials from your local machine.
On your local box where OAuth works, find ~/.claude/credentials.json. SCP it to the VPS:
scp ~/.claude/credentials.json tim@<your-ip>:~/.claude/credentials.json
ssh tim@<your-ip> "chmod 600 ~/.claude/credentials.json"
The credentials refresh themselves once on the VPS, no further OAuth needed.
Workaround B: API key only.
Create an API key in the Anthropic console, set it as an environment variable, skip OAuth entirely:
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.bashrc
source ~/.bashrc
Claude Code picks up the env var and skips the OAuth flow. This is the preferred approach if you are running headless agents under systemd (covered below) - each unit gets its own EnvironmentFile= with a per-agent key, which is what the credit split guide recommends anyway from 15 June.
Test the install: claude -p "say hello". You should get a response in a few seconds.
Security hardening: the fifteen-minute checklist
Default Ubuntu on a public IP is a target. Fifteen minutes of hardening makes it a boring target.
UFW firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable
If you are not running public webhooks, this is enough. If you are, open the specific port and put it behind Cloudflare Tunnel rather than exposing it raw.
fail2ban for SSH
fail2ban is already installed and enabled. The default jail bans IPs that fail 5 SSH attempts within 10 minutes, for 10 minutes. Verify:
sudo fail2ban-client status sshd
Within a day you will see a non-trivial banned-IP count. This is the internet doing what it does.
Disable password authentication
In /etc/ssh/sshd_config:
PasswordAuthentication no
PermitRootLogin no
Restart SSH: sudo systemctl restart ssh. Confirm you can still log in with your key before logging out (have a second SSH session open, just in case).
Tailscale for the SSH layer (recommended)
The biggest single security upgrade: stop exposing port 22 to the public internet. Install Tailscale:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Authorise the box in your Tailscale admin. Then close port 22 in UFW for the public internet, allow only the Tailscale interface:
sudo ufw delete allow OpenSSH
sudo ufw allow in on tailscale0
Your SSH is now only reachable from your Tailscale network. fail2ban is still there as belt-and-braces, but the attack surface from the open internet is zero. SSH from your phone (Tailscale iOS app) just works.
Automatic security updates
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
The box patches security updates overnight without you touching it.
What you actually run on the box
The point of the VPS is to host things that need to run when you are not at the desk. Typical stack for a UK indie hacker:
- systemd timers firing
claude -pjobs at scheduled times. Two-file pattern per job (covered in the Linux scheduling guide). - A Node listener for any inbound webhooks (Slack events, GitHub PR hooks, Discord interactions), behind Cloudflare Tunnel.
- A small Postgres if your agents share state. SQLite is fine for single-agent.
- Caddy or nginx if you are serving any HTTP at all, terminating TLS via Let's Encrypt.
A single CAX11 comfortably hosts five to ten production agents. The bottleneck is almost never the box - it is the per-agent API rate limit or your monthly Pool B cap. CPU usage on the box itself for an agent workload is typically under 5%.
Backups and disaster recovery
The honest weakness of a single small VPS: it is a single small VPS. If Hetzner has a regional outage or you typo a rm -rf, the box is gone. Three things to do once, then forget about:
- Hetzner snapshots. GBP 0.01 per GB per month. Take a weekly snapshot of the boot disk via the Hetzner Cloud console (or via the
hcloudCLI on a cron). Restoring is two clicks and roughly five minutes. - Off-box backups for the things that matter. Your
~/.claude/directory, your prompt files, anyEnvironmentFile=content, your systemd unit files.resticto Backblaze B2 is the cheapest credible target - around GBP 0.005 per GB per month, single-binary install. Schedule a daily backup via a systemd timer. - Infrastructure as code (lightweight). A single bash script that takes a fresh Ubuntu box and runs through the entire setup (apt installs, user creation, Claude Code install, agent unit files). Stored in a private GitHub repo. If the box dies, you provision a new one and run the script in fifteen minutes.
The point is not to build a fortress. The point is to make "my VPS exploded" a fifteen-minute inconvenience rather than a weekend of reconstructing a setup you barely remember building.
The cost summary
The all-in monthly cost for a UK indie hacker running laptop-close-persistent Claude Code agents:
- Hetzner CAX11 ARM VPS: ~GBP 3.30
- Tailscale (personal, free tier): GBP 0
- Cloudflare (free tier, with Tunnel): GBP 0
- Domain (if needed, .co.uk via Namecheap): ~GBP 0.50 amortised
- Claude Pro subscription: GBP 20
Total: ~GBP 23.30/mo for a setup that runs every agent you ship, survives every laptop close, gives you per-agent observability via journalctl, and stays well inside the Pool B cap from 15 June.
For perspective: a single Datadog APM seat is more than that. A Heroku Standard dyno is more than that. A serverless platform that "scales to zero" lies to you about its real cost the moment you actually use it. The small dedicated VPS at GBP 3.30 has been the cheapest credible production environment for indie software for a decade, and Claude Code does nothing to change the maths.
The pattern that ships
The UK indie hacker default in 2026:
- Rent a Hetzner CAX11 ARM (GBP 3.30/mo).
- SSH in, create a non-root user, UFW + fail2ban, Tailscale for the SSH layer.
- Install Claude Code via the install script.
- Authenticate with the SCP-credentials workaround or skip OAuth entirely with
ANTHROPIC_API_KEYenv vars. - Drop your
claude -pagents into systemd timer units withOnFailure=handlers. - Use per-agent API keys with per-key daily caps for Pool B isolation.
That is the stack. Twenty minutes from clicking "Create Server" to your first agent running on its own schedule, with logs in journalctl and failure alerts in Slack, for less than the price of a pint a month. Once it is running you mostly forget the box exists, which is the highest compliment you can pay any piece of infrastructure.
New here? IdeaStack publishes one deeply researched UK business opportunity every Thursday - real keyword data, competitor analysis, builder prompts. See the latest free report.
Frequently asked
Why run Claude Code on a VPS instead of just my laptop?
Persistence. A laptop sleeps when you close it, kills background processes, drops VPN connections, and loses scheduled tasks. A VPS stays on. For any Claude Code agent that needs to fire at a specific time, hold a webhook open, or respond to a Slack ping at 11pm, the VPS is the thing keeping the lights on. The cheapest credible UK-friendly option is around GBP 3.30 a month on Hetzner ARM, which is less than a coffee and gives you a real always-on Linux box.
Is the Cloudflare OAuth issue on Hetzner real?
Yes. GitHub issue anthropics/claude-code #21678 confirms that the Cloudflare JS challenge on Anthropic's OAuth endpoint blocks the token exchange from Hetzner Cloud IP ranges. The symptom is the OAuth flow hanging or 403-ing during authentication. The workaround is straightforward: authenticate on your local machine, then SCP the credentials file to the VPS, or run with an API key in an environment variable instead of OAuth. Both work cleanly and are documented below.
Why Hetzner specifically and not a UK provider?
Hetzner Falkenstein and Helsinki are around 20 to 30 ms from the UK, which is fine for Claude Code. The price point is unbeatable in 2026: roughly GBP 3.30 a month for a 2-core ARM VPS with 4GB RAM. UK providers like Mythic Beasts, Bytemark, and Hostinger run from GBP 4 to GBP 8 a month for comparable specs. Mythic Beasts is the right pick if you specifically need UK data residency for client work; for everyone else Hetzner ARM is the cheapest credible option.
Should I run Claude Code as root on the VPS?
No, never. Create a non-root user, give it sudo only for specific commands you actually need, run Claude Code under that user. Run UFW with only SSH and Tailscale open, fail2ban on SSH, key-based authentication only, password authentication disabled. Better: put SSH behind Tailscale so the SSH port is not exposed to the public internet at all. The full hardening checklist below takes about fifteen minutes and rules out the obvious attack surfaces.
Can I run multiple Claude Code agents on a single VPS?
Yes, easily. The 2-core 4GB Hetzner ARM box runs five to ten production agents comfortably under systemd timers, each scheduled independently, each logging to its own journalctl unit, each with its own EnvironmentFile holding a per-agent API key. The bottleneck is almost never the box itself - it is the per-agent API rate limit or your monthly Pool B cap. One small VPS is enough for the typical UK indie hacker production fleet.
Filed under




