Skip to main content
← All episodes

Episode 3

Server (optional)

Clicking loads the video from YouTube (youtube-nocookie.com). Nothing is sent to YouTube before that. Privacy policy

In this episode (≈ 90 min of hands-on work)

  • Your own server, reachable only through your private Tailscale network.
  • Claude Code in a sealed-off container with no open ports.
  • A session that keeps running while you steer it by phone.

Your step

Paste this into Claude Code on your laptop before you order anything. Claude walks you through the checklist and stops wherever money or your accounts are involved.

Walk me through ~/ailoopwise-blueprint/course/examples/server-checklist.md, one item at a time and in its order. I am not a developer, so explain each item in one plain sentence.
1. For each item, show me the matching command or click path from ~/ailoopwise-blueprint/course/03-server-optional.md, then wait until I tell you the result before you go on.
2. STOP before anything that costs money or happens in one of my accounts (ordering the server, Hetzner, Hostinger, Tailscale, GitHub). Tell me what to do there myself and wait until I say it is done.
3. Do not let me switch on ufw before login over the Tailscale address (100.x.y.z) works, or I lock myself out.
4. Change nothing yourself, in this folder or outside it. You may run commands that only display something on this computer, after explaining them. I type everything else myself.
5. Never open or print the private key ~/.ssh/id_ed25519 (only the .pub file is shared), and never print passwords, tokens or login codes.
6. Never run git commit or git push unless I ask. At the end, list the items that are still open.

Files for this episode

Questions about this episode? Just email us: hello@ailoopwise.com

Step-by-step guide

What this episode is about

This episode is an extra. If it feels too technical, skip it. Episodes 4 to 6 don't need a server.

You rent a small virtual server (Hetzner or Hostinger) and run Claude Code there in a sealed-off Docker container. Tailscale makes the server invisible from outside. On your phone you open Termius, attach to a tmux session so nothing drops, and with /remote-control you can also drive the session from the Claude app. The laptop can stay shut.

The wall: a server also means updates, backups and access rights, forever, not once.

What you need
Step by step
  1. Create an SSH key on the laptop (Enter for the default path, then set a passphrase):
    ssh-keygen -t ed25519 -C "laptop"
    cat ~/.ssh/id_ed25519.pub
    
    Only share that .pub line. The file without .pub stays on the laptop.
  2. Order the server. Hetzner: in your project Servers → Add server, image Ubuntu, a type with at least 4 GB RAM, paste the .pub line under SSH key. At Hetzner this only works at creation (guide). Hostinger: add the key during setup or later under VPS → Manage → Settings → SSH keys (guide). No password login.
  3. Log in: ssh root@<public-IP>
  4. Tailscale on the server: install from https://tailscale.com/kb/1031/install-linux (use the command there), then:
    sudo tailscale up
    tailscale ip -4
    
    Open the URL shown and sign in with the same account as on laptop and phone. Note the 100.x.y.z address.
  5. Log back in over Tailscale (exit, then ssh root@100.x.y.z) and only then block everything else (steps from https://tailscale.com/kb/1077/secure-server-ubuntu):
    sudo ufw allow in on tailscale0
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    sudo ufw enable
    sudo ufw status verbose
    
    Test from the laptop: ssh root@<public-IP> times out, ssh root@100.x.y.z works.
  6. Docker: install from https://docs.docker.com/engine/install/ubuntu/, then tmux: sudo apt install tmux
  7. Start the container and add jq (the blueprint hooks need it):
    sudo docker run -dit --name claude-box --restart unless-stopped \
      --user node -w /home/node -v claude-home:/home/node node:22 bash
    sudo docker exec -u root claude-box apt-get update
    sudo docker exec -u root claude-box apt-get install -y jq
    
    Claude runs there as user node, not root. The home directory lives in the claude-home volume, so login and projects survive a restart. No -p: no container port is reachable from outside.
  8. Blueprint onto the server (first line on the laptop, the others on the server):
    scp -r ~/ailoopwise-blueprint root@100.x.y.z:/root/
    sudo docker cp /root/ailoopwise-blueprint claude-box:/home/node/
    sudo docker exec -u root claude-box chown -R node:node /home/node/ailoopwise-blueprint
    
  9. Open a tmux session and enter the container:
    tmux new -As claude
    sudo docker exec -it claude-box bash
    
    Install Claude Code inside the container with the Linux command from https://code.claude.com/docs/en/setup and check with claude --version.
  10. Sign in: start claude. No browser opens on a server: press c, open the copied URL on laptop or phone, sign in, and paste the code shown at Paste code here if prompted.
  11. Set up the project as in episode 2, just in the terminal: cd ~/ailoopwise-blueprint, claude, paste the prompt from episode 2. Then cd ~/<your-project> and claude. Accept the trust dialog once.
  12. Termius on the phone: Keychain → Generate Key (Ed25519), add a host with 100.x.y.z, user root, that key. Then push the key to the server with Export to host (guide). Connect and run:
    tmux attach -t claude
    
  13. Turn on Remote Control, in the running session in the phone terminal:
    /remote-control
    
    Confirm Enable Remote Control. In the Claude app, tap Code and find the session with a computer icon and a green dot.
  14. Let go: Ctrl+b, then d detaches you; Claude keeps running. The docs: "To keep a session running on a remote machine after you disconnect from SSH, start it inside tmux or screen." (Remote Control)

Security, no exceptions: SSH keys, not passwords. After step 5, port 22 is closed to the public. Publish no container ports: ports published with -p bypass ufw (Docker docs). Never put API keys in the image or Dockerfile, never mount ~/.ssh or cloud credentials into the container (Claude Code docs). While Remote Control is connected, the session transcript is stored on Anthropic's servers; everything still executes on your server.

Example to copy

The full order to tick off: examples/server-checklist.md. The core:

- [ ] ufw: `allow in on tailscale0`, all other incoming blocked, enabled
- [ ] Container `claude-box` runs as user `node`, with no published ports (`-p`)
- [ ] No API key in the image, no `~/.ssh` or cloud credentials mounted
Before the next episode

Shut the laptop, connect with Termius, type tmux attach -t claude and check that your session is still running.

If something goes wrong

Free by email

New guides by email, plus the complete Blueprint package

With every new video you get the full guide with the ready-to-paste AI brief. Once you confirm your address, the complete Blueprint package is the first thing we send you.

Free. Unsubscribe any time.

Episode 3: Server (optional) | Claude Code course by AILoopwise