How to Run Claude Code on a VPS: Beginner Step-by-Step Guide (2026)

Last week, Rob Hallam (@robj3d3) posted a setup on X that blew up: a cheap VPS that runs Claude Code around the clock, locked down so tight it’s invisible to the public internet, and administered entirely by the AI itself. You open an SSH app on your phone, type what you want, and your server does it.

The original post packs 16 steps into tweet format, and a lot of people in the replies called it complex. It’s not complex. It’s dense. So here’s the beginner-friendly version. I’ll show you how to run Claude Code on a VPS step by step, explain why each step exists, and give you a copy-paste agent prompt at the end that hands the whole server over to Claude.

Full credit for this setup goes to Rob Hallam. He designed it and shared it publicly. All I’m doing here is unpacking it so a beginner can actually follow along.

Table of Contents


What You’re Actually Building

Before touching anything, let’s get the mental model right. You’re setting up four things that work together:

  • A VPS (virtual private server): a small rented Linux machine that runs 24/7 for the price of two coffees a month.
  • Tailscale: a free private network between your devices. Your laptop, your phone, and your server can talk to each other, and nobody else can even see the server exists.
  • Cloudflare: sits in front of your domain, so the only public traffic that ever reaches the server is web traffic coming through Cloudflare.
  • Claude Code: Anthropic’s terminal AI agent. It lives on the server inside a tmux session and does all the actual admin work. You just tell it what you want.

The end result: a server you never administer by hand. You connect from any device, say “set up a new site for this domain” or “why is the app down”, and Claude Code handles it. The security model means there’s no public SSH port for anyone to attack. Your entrance is a private tunnel.

Rob claims about 40 minutes for the whole setup. As a beginner, give yourself a relaxed afternoon. Nothing here is hard, but you’ll want to read as you go instead of racing through it.

What You Need

  • Around €5 to €10 a month for the VPS.
  • A domain you own (any registrar works, we’ll point it at Cloudflare).
  • A Claude account with a paid plan or API access, since Claude Code needs one to log in.
  • Free accounts for Cloudflare, Tailscale, and Termius.
  • Zero Linux experience. That’s the point of the whole article.

Part 1: Buy Everything (About 15 Minutes)

Step 1: Get a cheap VPS

Go to Hetzner or DigitalOcean and create the smallest cloud server they offer. Pick Ubuntu 24.04 as the operating system. At checkout, tick the box for automatic backups. It costs a little extra and it will save you one day.

Being German, I’ll point you to Hetzner. Their small cloud instances are ridiculously good value and the data centers are in the EU. DigitalOcean is just as fine if you prefer it.

Don’t finish the creation process yet if your provider asks for an SSH key. We’ll generate one in Step 4, and adding it during creation is the cleanest way. If you already created the server, no problem, you can add the key afterwards too.

Step 2: Put your domain behind Cloudflare

Create a free Cloudflare account and add your domain. Cloudflare gives you two nameservers. Log into your registrar (where you bought the domain) and replace the existing nameservers with those two. Propagation usually takes minutes, sometimes a few hours.

Why bother? Because later we’ll configure the server firewall so that only Cloudflare can reach your websites. Attackers scanning the internet will find nothing. Cloudflare also gives you free HTTPS and caching on top.

Step 3: Install Termius and Tailscale on your devices

Install two apps on both your laptop and your phone:

  • Termius: a friendly SSH client. This is the app you’ll open to talk to your server. The free tier is enough.
  • Tailscale: the private network. Sign in with the same account on every device. Free tier covers this whole setup.

Part 2: Lock It Down (About 20 Minutes)

This is the part that scared people off in the replies. Take it slow and follow the order exactly. The order matters because we test the private entrance before we brick up the public one.

Step 4: SSH keys only, never passwords

In Termius, go to Keychain and generate a new SSH key (Ed25519 is the default and it’s fine). An SSH key is a pair of files: a private half that never leaves your device and a public half you hand to the server. It replaces passwords entirely and can’t be brute-forced.

Paste the public key into your VPS provider’s SSH key field when creating the server. Password login should stay off forever.

Step 5: First login, updates, and Tailscale on the server

In Termius, create a new host with your server’s public IP, user root, and your new key. Connect. You’re in a Linux shell now. Run updates first:

apt update && apt upgrade -y

Then install Tailscale on the server and log it into your network:

curl -fsSL https://tailscale.com/install.sh | sh
tailscale upCode language: JavaScript (javascript)

Tailscale prints a URL. Open it in your browser, approve the machine, done. Your server is now part of your private network and has a second IP address starting with 100.

Step 6: Disable Tailscale key expiry for the server

Tailscale logins expire after a few months by default. Fine for laptops, terrible for a server you never want to touch. In the Tailscale admin console, find your server in the machine list, open the three-dot menu, and click Disable key expiry. One click, never think about it again.

Step 7: Verify Tailscale SSH works BEFORE locking anything

This step is the seatbelt. In Termius, add a second host entry using the server’s Tailscale 100.x address instead of the public IP. Connect to it. If it works, great. If it doesn’t, stop and fix it before moving on.

Do not skip this. In the next step we slam the public door shut, and the Tailscale address becomes your only way in.

Step 8: Close the firewall

Now go to your provider’s firewall settings (Hetzner Cloud Firewall or DigitalOcean Cloud Firewall, in the web dashboard, not on the server itself). Delete every inbound rule. Then add exactly one: allow TCP port 443, but only from Cloudflare’s published IP ranges.

That’s it. No public SSH. No open ports for bots to poke at. Web visitors come in through Cloudflare on 443, and you come in through the Tailscale tunnel, which doesn’t need any inbound firewall rule at all.

Step 9: Test from outside. The server is now invisible

Try to SSH to the public IP. It should hang and time out. Ping it, nothing. Then connect via the Tailscale address, works instantly. From the public internet, your server no longer exists. This is a much stronger position than the usual “install fail2ban and hope” approach.

Step 10: One SSH key per device

Generate a separate key in Termius on your phone, then append its public half to the server’s ~/.ssh/authorized_keys file (one key per line). Never copy a private key between devices. If you lose your phone, you delete one line on the server and that device is locked out.

Part 3: Run Claude Code on the VPS (About 5 Minutes)

Step 11: Install tmux and Claude Code

apt install tmux -y
curl -fsSL https://claude.ai/install.sh | bashCode language: JavaScript (javascript)

The second command is the official native installer for Claude Code. On first run it will ask you to log in with your Claude account by opening a URL on another device. Follow the prompt once and it stays logged in.

Step 12: Run Claude Code inside tmux

tmux is a terminal that keeps running on the server after you disconnect. This is what makes the whole thing magical. Claude Code can chew on a 20-minute task while your laptop is closed and your phone is in your pocket.

tmux new -s claude
claudeCode language: JavaScript (javascript)

To leave the session running and disconnect, press Ctrl+b, then d. To come back later from any device, run tmux attach -t claude. That’s the entire workflow you’ll use daily.

Part 4: Hand the Server Over to Claude

Here’s the clever bit of Rob’s setup. Instead of learning server administration, you write one long handover prompt that tells Claude Code everything about the machine: the facts, the security model, the folder conventions, and the standing rules. Then you make it write all of that into a CLAUDE.md file, which Claude Code reads automatically at the start of every future session.

Two details in the prompt matter more than the rest. First, you spell out the security model explicitly so Claude doesn’t helpfully “fix” your locked firewall when something seems unreachable. Second, backups come before features. A nightly job that pushes your data to a private GitHub repo, tested with a real restore, before a single page goes live.

After that, you let Claude install the web server itself. Rob recommends Caddy with the Cloudflare DNS plugin, because it gets HTTPS certificates via DNS and plays nicely with the locked-down firewall. I run Caddy behind Cloudflare myself, and it’s a solid combo (with one small gotcha around social cards I wrote about in Twitter Card Not Showing? The Cloudflare Redirect Trap).

From then on, you never administer the server again. You open Termius from anywhere and say what you want. If you’re curious what daily work with Claude Code looks like, I covered my own workflow in Ship Faster with ChatGPT Codex + Claude Code.

The Copy-Paste Agent Prompt

Here’s a full handover prompt you can paste into Claude Code as your first message. Replace the placeholders in square brackets with your own values first.

You are the system administrator of this server. I am a beginner and you handle all admin work from now on. Read everything below carefully. Then, before doing anything else, write all of this information into a CLAUDE.md file in the current directory so every future session starts with full context.

SERVER FACTS
- Provider: [Hetzner / DigitalOcean], smallest cloud instance, Ubuntu 24.04
- Public IP: [YOUR_PUBLIC_IP] (locked down, do not rely on it for access)
- Tailscale IP: [YOUR_100.x_ADDRESS]. All SSH access happens through Tailscale only.
- Domain: [yourdomain.com], DNS is managed in Cloudflare
- Automatic provider backups are enabled

SECURITY MODEL (never change this, never "fix" it)
- The provider firewall allows inbound TCP 443 from Cloudflare's published IP ranges only. Nothing else is open to the public internet, including SSH.
- SSH is key-only. Password authentication stays disabled permanently.
- Never open new public ports. Every new service you install must bind to localhost or the Tailscale interface only, unless I explicitly approve otherwise.
- Never install or reconfigure firewall tools (ufw, iptables, fail2ban) without asking me first.
- If something seems unreachable from outside, the firewall is working as intended. Ask me before touching any network configuration.

FOLDER CONVENTIONS
- Each project lives in /srv/http/[domain], one folder per site or app.
- Each project runs in its own tmux session, named after the domain.
- The web server is Caddy with the Cloudflare DNS plugin. All sites are defined in one Caddyfile.
- Databases are SQLite files inside the project folder unless a project clearly outgrows that.

STANDING RULES
- Confirm with me before any destructive action: deleting files, dropping databases, removing packages, overwriting configs, anything involving rm.
- Backups before features. A nightly backup job that pushes my data to a private GitHub repository must exist and pass a real restore test before we deploy anything.
- Keep the system updated, but tell me before major version upgrades.
- After every task, summarize what you changed and where.
- When unsure about anything touching security, DNS, or data, ask instead of guessing.

MY PREFERENCES
- Explain what you are doing in plain language as you go. I want to learn.
- Prefer boring, standard tools over clever custom solutions.
- [Your timezone, language, stack preferences, anything else]

FIRST TASKS, IN THIS ORDER
1. Write this entire handover into CLAUDE.md.
2. Set up the nightly backup job to a private GitHub repo and prove it works with a restore test.
3. Install Caddy with the Cloudflare DNS plugin and serve a placeholder page for [yourdomain.com] over HTTPS.
4. Set up SQLite and show me where project data will live.

Confirm you have understood the security model before you start.Code language: PHP (php)

FAQ

Do I need Linux experience to run Claude Code on a VPS?

No. You need to copy about five commands and click through a few dashboards. Everything after the setup is done by Claude Code itself, and the handover prompt tells it to explain its work in plain language.

How much does this setup cost per month?

The VPS is €5 to €10 a month. Cloudflare, Tailscale, and Termius all have free tiers that cover this use case. On top of that you need a paid Claude plan or API credits for Claude Code.

Is it safe to let an AI agent administer a server?

Safer than you’d think, if you do it like this. The server holds no secrets at the start, the firewall makes it invisible, backups run nightly, and the standing rules force Claude to confirm before destructive actions. The blast radius of a mistake is one cheap, backed-up box.

Why not just run Claude Code on my laptop?

Because a laptop sleeps, disconnects, and travels. The tmux session on the VPS keeps working while your laptop is closed. You can kick off a task from your phone on the train and check the result an hour later.

What if I lock myself out?

That’s what Step 7 prevents, and it’s why the order matters. If it happens anyway, every provider has a web-based emergency console in the dashboard that works regardless of the firewall. Log in there and fix your Tailscale connection.

Where to Go From Here

Follow the 16 steps once and you own an always-on AI-administered server for the price of a Netflix subscription. Start small: let Claude deploy a static page, then a little app with SQLite, and grow from there. If you want to peek over Claude’s shoulder now and then, my roundup of Linux monitoring tools is a good place to start.

And go follow Rob on X. This setup is his, and he ships stuff like this constantly. BOSH, as he’d say.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap