stu mason. TC 00:00:00:00

remote claude · setup guide

Run Claude Code on a server, not your laptop.

Put Claude Code on a VPS, then use the same session from your laptop, a terminal, or your phone. It keeps running when you disconnect, and it can run agents that start their own agents. This is the whole setup, copy-paste.

why · the idea

The hard part isn't the AI. It's the plumbing.

Claude Code does its thinking on Anthropic's servers, not your machine — so where the process actually runs barely affects speed. Move it onto a small server that never sleeps or loses WiFi, and you can connect from anywhere, leave it working, and come back to it later.

01

One session, any device

Laptop, terminal and phone all attach to the same running session. Start something on one, carry on from another.

02

Agents that run agents

Dispatch background agents from one place; each can spin up its own workers. You watch the tree and steer.

03

Kept separate from prod

It runs in an isolated container — no host access, no open ports — so it can't reach anything else on the box.

04

Survives disconnects

Lose signal or close the lid and the work continues. Reconnect and you're back where you left off.

proof · it's running

What it looks like.

Left: the agent fleet view inside VS Code, attached to the container on the server. Right: a single session running two agents at once, each starting its own workers.

Claude Code agent fleet view inside VS Code, attached to the remote container
fig.01  the fleet · vs code → container → server
A single Claude session running two background agents, each spawning workers
fig.02  agents starting agents

architecture · how it fits together

How it fits together.

client
Laptop · VS Code
remote-ssh / attach
client
Phone · SSH app
termius / blink
tailscale — private network, no public ports
your vps · docker
container “claude-sandbox”
non-root · isolated · persistent volumes
inside the container
tmux “main” — one session, shared by every device claude — on your Claude plan claude agents — background fleet, each can spawn workers your toolchain — node, php, python, ffmpeg, chromium, gh…

setup · copy-paste

The steps.

You'll need a VPS with Docker, a Claude Pro/Max plan, a free Tailscale account, and an SSH app on your phone.

01

Build the image

A VS Code (code-server) base with Claude Code and your toolchain baked in. Bake what you actually use — anything you apt install at runtime is lost on the next rebuild.

Dockerfile
FROM codercom/code-server:latest
USER root

# Node 22 (Claude Code), git, ripgrep, tmux, gh CLI, headless Chromium
RUN apt-get update && apt-get install -y --no-install-recommends \
      curl git ripgrep ca-certificates less tmux chromium fonts-liberation \
  && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
  && apt-get install -y nodejs \
  && npm install -g @anthropic-ai/claude-code \
  && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
       -o /usr/share/keyrings/gh.gpg && chmod go+r /usr/share/keyrings/gh.gpg \
  && echo "deb [signed-by=/usr/share/keyrings/gh.gpg] https://cli.github.com/packages stable main" \
       > /etc/apt/sources.list.d/github-cli.list \
  && apt-get update && apt-get install -y gh \
  && apt-get clean && rm -rf /var/lib/apt/lists/*

# Dev stack: media, PHP 8.4 + Composer, Python, DB clients, utils, yt-dlp
RUN apt-get update && apt-get install -y --no-install-recommends \
      ffmpeg imagemagick \
      php8.4-cli php8.4-mbstring php8.4-xml php8.4-curl php8.4-zip php8.4-bcmath \
      php8.4-intl php8.4-gd php8.4-pgsql php8.4-sqlite3 php8.4-mysql php8.4-redis \
      python3-pip python3-venv pipx \
      sqlite3 postgresql-client redis-tools jq build-essential rclone \
  && curl -fsSL https://getcomposer.org/installer | php -- \
       --install-dir=/usr/local/bin --filename=composer \
  && curl -fsSL https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp \
       -o /usr/local/bin/yt-dlp && chmod a+rx /usr/local/bin/yt-dlp \
  && apt-get clean && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /home/coder/workspace && chown -R coder:coder /home/coder
USER coder
02

Run it — persistent and isolated

Volumes keep your login, history and files across restarts. No docker.sock and no host mounts, so the container can't reach the rest of the machine.

docker-compose.yml
services:
  claude-sandbox:
    build: .
    container_name: claude-sandbox
    working_dir: /home/coder/workspace
    shm_size: '4gb'              # headless Chrome needs it (RAM, not disk)
    restart: unless-stopped
    volumes:
      - ./workspace:/home/coder/workspace
      - claude:/home/coder/.claude        # login + history persist
      - cfg:/home/coder/.config           # gh + tmux config persist
volumes: { claude: , cfg: }
terminal
docker compose up -d --build
03

Sign in on your plan

Generate a token on a machine with a browser (a headless server can't complete the login callback), then give it to the container. It uses your subscription — no API key, no per-token billing.

on your laptop
claude setup-token        # logs in via browser, prints a token
in the container
# set CLAUDE_CODE_OAUTH_TOKEN=<token> in the container, then for GitHub:
docker exec -it claude-sandbox gh auth login
04

Private access with Tailscale

Tailscale puts your server and devices on one private network. Nothing is exposed to the public internet — you reach the box by its Tailscale name, and only from your own devices.

on the server (and each device)
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up        # open the link it prints, then authorise
05

One session on every device

A one-line helper drops you into the same tmux session from anywhere — so phone, laptop terminal and VS Code share one running thread.

/usr/local/bin/sandbox  (on the server)
#!/usr/bin/env bash
exec docker exec -it -u coder claude-sandbox \
     tmux new -A -s main        # attach if it exists, else create
~/.ssh/config  (your laptop) → "ssh sandbox"
Host sandbox
    HostName <server-tailscale-ip>
    User root
    RequestTTY yes
    RemoteCommand /usr/local/bin/sandbox
Phone: in your SSH app, point the key's forced command at /usr/local/bin/sandbox — connecting drops straight into the session, and that key can't reach anything else on the server. VS Code: Remote-SSH or Attach-to-Container, then set the terminal profile to tmux new -A -s main.
06

Run agents that run agents

Open the fleet view and dispatch background agents; each can start its own workers. Turn on auto mode — a safety classifier auto-approves routine steps but still stops before anything destructive.

~/.claude/settings.json
{ "permissions": { "defaultMode": "auto" } }
in the session
claude agents        # the fleet — dispatch, watch, redirect
07

Move files both ways

Put your own machine on Tailscale too, and it's on the same private network as the sandbox — so files go in either direction. Taildrop sends a file straight to a device's Downloads, no SSH keys or shares to set up.

from the sandbox → your laptop
tailscale file cp render.mp4 my-laptop:      # lands in Downloads
from your laptop → the sandbox
tailscale file cp brief.pdf claude-sandbox:
Taildrop drops files into Downloads for you to pick up — so an agent can hand you a finished render or a report without ever getting write-access to the rest of your machine.

For bigger files, artifacts, or a shared drive every device reads and writes, use R2 (or any S3 bucket). rclone is already in the image — point a remote at your bucket and sync both ways.

shared bucket — push from the sandbox, clone on your Mac
rclone copy render.mp4 r2:my-bucket/out/     # push from anywhere
rclone copy r2:my-bucket/out ./out           # pull a local clone
No NAT to fight, no network to set up — and the data lives in storage you own.

security · sensible defaults

Keep it contained.

·

Isolated container

Runs non-root, with no docker socket and no host mounts. It can't see or touch the rest of the server.

·

No public ports

Everything goes over Tailscale. There's nothing on the public internet to scan or brute-force.

·

Auto mode, not blind trust

Routine work flows; destructive actions still pause for you. Full bypass stays opt-in, for throwaway work.

·

Optional egress allowlist

Running an agent unattended with real keys? Lock outbound traffic to a short list so nothing can leak.

the point

The work runs on the server.

So the laptop matters a lot less — anything that can open VS Code or an SSH terminal drives it the same way. It runs on your Claude subscription, on a server you rent for around £30 a month, and you can reach it from your phone.