Claude Code on a Persistent Cloud VM

Running Claude Code CLI on an always-on Linux VM so Remote Control works from iPad anytime.

Links: iPad + Claude Setup, Working With Claude, The Cyborg Model

The Problem

Remote Control requires a running claude process on a machine. The Windows PC sleeps, corporate firewalls may block websockets, and the ~10-minute network timeout kills the session. A persistent cloud VM solves all three.

Architecture

iPad (Claude app / safari) 
  → claude.ai/code (Remote Control UI)
  → Anthropic API (TLS relay)
  → Cloud VM (tmux → claude remote-control)
  → vault repo (git clone)

All traffic is outbound HTTPS from the VM. No inbound ports needed.

1. Can Claude Code Run on Headless Linux?

Yes. Confirmed working on Debian 12 headless (no display server) via SSH + tmux (GitHub issue #29479). The setup:

2. Authentication — The Critical Constraint

Remote Control requires OAuth login, not API keys. This is the single most important constraint.

Auth Method Remote Control? How to Set Up on Headless
/login (OAuth) Yes Run claude, it prints a URL; open that URL in a browser on any device; complete login; token flows back to CLI
ANTHROPIC_API_KEY No export ANTHROPIC_API_KEY=sk-... — works for headless Claude but NOT Remote Control
claude setup-token No Generates a 1-year OAuth token, but scoped to inference only — explicitly “cannot establish Remote Control sessions”

Workflow for headless auth:

  1. SSH into VM
  2. Run claude — it prints a login URL (no browser opens)
  3. Copy URL, paste into iPad/phone browser
  4. Complete OAuth on claude.ai
  5. Token persists in ~/.claude/.credentials.json (mode 0600)
  6. Only need to redo if you /logout or token expires

Requires: Pro, Max, Team, or Enterprise plan.

3. Running Remote Control in tmux

# SSH into VM
ssh user@vm-ip

# Start or attach tmux
tmux new -s vault || tmux attach -t vault

# Navigate to vault
cd ~/vault

# Start Remote Control (server mode — best for this use case)
claude remote-control --name "Vault" --spawn session

# Press spacebar to show QR code
# Or copy the session URL

The --spawn session flag limits to one session (simpler). Omit it for multi-session.

Known limitation: claude remote-control currently requires a TTY. Cannot run as a systemd service or via nohup. tmux/screen is the workaround. A --headless flag is requested (GitHub issue #30447) but not yet implemented.

Keep-Alive Script

#!/bin/bash
# ~/start-vault-rc.sh
# Run inside tmux. Restarts Remote Control if it exits.
while true; do
  cd ~/vault && git pull --ff-only
  claude remote-control --name "Vault" --spawn session
  echo "Session exited at $(date). Restarting in 10s..."
  sleep 10
done

4. Git Sync

# Initial clone
git clone https://github.com/chrisaacson69/vault.git ~/vault

# Auth via SSH key (recommended) or GitHub CLI
ssh-keygen -t ed25519 -C "vault-vm"
# Add public key to GitHub → Settings → SSH Keys

# Or use gh CLI
gh auth login  # device code flow — works headless

For two-way sync (VM edits + local edits), just use git normally. The VM and local PC are both working copies of the same repo. Push from whichever you edit on; pull on the other.

5. Cheapest Always-On VM Options

Provider Plan Specs Monthly Cost Notes
Hetzner Cloud CX22 Shared vCPU 2 vCPU, 4 GB RAM, 40 GB SSD ~$4.15 (€3.79) Best value. EU + US regions. 20 TB traffic
Vultr Cloud Compute 1 vCPU, 1 GB RAM, 25 GB SSD $2.50 Cheapest entry point
AWS Lightsail Nano 1 vCPU, 512 MB RAM, 20 GB SSD $3.50 May be tight on RAM
Linode (Akamai) Nanode 1 vCPU, 1 GB RAM, 25 GB SSD $5.00 Solid reliability
DigitalOcean Basic Droplet 1 vCPU, 1 GB RAM, 25 GB SSD $6.00 Good docs, easy setup
Fly.io Shared 256MB shared vCPU, 256 MB RAM ~$2/mo + $2 IPv4 Too little RAM
GitHub Codespaces 2-core 2 vCPU, 8 GB RAM $129.60 if always-on Terrible for 24/7

Recommendation: Hetzner CX22 at ~$4/month

Vultr at $2.50 works too but Hetzner gives 4x the RAM for $1.65 more.

6. Why NOT GitHub Codespaces

7. Docker Option

Anthropic publishes an official image: ghcr.io/anthropics/claude-code:latest (487 MB, multi-arch).

docker run -it \
  -v ~/vault:/workspace \
  -e ANTHROPIC_API_KEY=sk-... \
  ghcr.io/anthropics/claude-code:latest

However, for the Remote Control use case, Docker adds complexity without benefit:

8. Complete Setup Checklist

  1. Create VM: Hetzner CX22, Ubuntu 24.04, SSH key auth
  2. SSH in: ssh root@<ip> → create non-root user
  3. Install Claude Code:
    curl -fsSL https://claude.ai/install.sh | sh
    
  4. Install tmux: apt install tmux
  5. Clone vault:
    gh auth login  # or set up SSH key
    git clone git@github.com:chrisaacson69/vault.git ~/vault
    
  6. Authenticate Claude Code:
    cd ~/vault
    claude
    # Copy the URL it prints → open on iPad → complete OAuth
    
  7. Start Remote Control:
    tmux new -s vault
    cd ~/vault
    claude remote-control --name "Vault"
    # Ctrl-B D to detach
    
  8. Connect from iPad: Open Claude app → Code tab → find “Vault” session (green dot)

Total recurring cost: ~$4/month (Hetzner) + existing Claude Max subscription.

9. Alternatives to Consider

Open Questions

Tags

ai