Sometimes I’m using Codex on my Macbook and I have to leave for class. I don’t want to lose that session/flow, I want to be able to keep prompting on my phone while I’m waiting for the bus or the trolley.

So I decided to setup a Hetzner VPS to keep my terminal sessions alive, Tailscale lets you connect from anywhere, tmux preserves the session.

The Stack

  • VPS (Hetzner, $5/mo), I’m using Hetzner cpx11 (Hillsboro, Oregon)
  • Tailscale - private 100.x.x.x IP, no port forwarding needed
  • tmux - sessions persist when you disconnect

VPS Setup

First thing after spinning up Ubuntu 24.04:

sudo apt update && sudo apt upgrade -y

Generate an SSH key on your laptop if you don’t have one:

ssh-keygen -t ed25519
cat ~/.ssh/id_ed25519.pub

Paste that into your VPS provider.

Lock down SSH

SSH in as root once to create a non-root user:

adduser dev
usermod -aG sudo dev
rsync -a ~/.ssh /home/dev
chown -R dev:dev /home/dev/.ssh

Then disable root login and passwords in by doing sudo nano /etc/ssh/sshd_config and then adding into the file:

PermitRootLogin no
PasswordAuthentication no

Restart SSH and test with a new terminal before closing your root session:

sudo systemctl restart ssh

Tailscale Setup

Tailscale gives your server a private IP that only your devices can reach. On your VPS run:

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg \
| sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
 
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list \
| sudo tee /etc/apt/sources.list.d/tailscale.list
 
sudo apt update && sudo apt install tailscale -y
sudo tailscale up
tailscale ip -4

Install Tailscale on your phone and laptop with the same account. Now you can SSH to 100.x.x.x from anywhere.

Restrict SSH to Tailscale only

This makes your server only accessible via Tailscale.

sudo ufw allow in on tailscale0 to any port 22
sudo ufw deny 22
sudo ufw enable

Note for Hetzner

If you’re using Hetzner’s cloud firewall, you might want to skip UFW and just use their firewall instead. Using both can get confusing.

tmux

This is so your sessions survive disconnects.

sudo apt install tmux -y

Optional but nice - mouse support and a shortcut alias:

echo "set -g mouse on" >> ~/.tmux.conf
echo "alias dev='tmux attach -t dev || tmux new -s dev'" >> ~/.bashrc
source ~/.bashrc

Now just type dev to attach or create a session (or tmux new -s dev / tmux attach -t dev without the alias). Detach with Ctrl+b then d.

Install your tools

Node.js

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
\. "$HOME/.nvm/nvm.sh"
nvm install 24

Claude Code

curl -fsSL https://claude.ai/install.sh | bash

Codex

npm install -g @openai/codex

OpenCode

curl -fsSL https://opencode.ai/install | bash

Droid

curl -fsSL https://app.factory.ai/cli | sh

Git SSH Setup

If you want to clone private repos or push to GitHub from your VPS, you need to set up a separate SSH key for Git.

Generate a new key on the VPS:

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_github
cat ~/.ssh/id_ed25519_github.pub

Add the key to GitHub:

  • Go to GitHub → Settings → SSH and GPG keys → New SSH key in the browser
  • Paste the public key, name it something like hetzner-vps

Create an SSH config so Git uses the right key:

nano ~/.ssh/config

Add this:

Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes

Set permissions and test:

chmod 600 ~/.ssh/config
ssh -T git@github.com

It should say “Hi username! You’ve successfully authenticated”. Now you can clone repos.

No passphrase

If you set a passphrase when generating the key, you’ll have to type it every time. For tmux + phone usage, it’s easier to have no passphrase. You can remove it with ssh-keygen -p -f ~/.ssh/id_ed25519_github.

Connect to your VPS from your phone

  • Install Tailscale on your phone
  • Use Termius or any SSH client
  • Connect to 100.x.x.x and use the username dev, also add in your SSH key
  • Type dev to attach to your tmux session

That’s it. Your phone can now use Claude Code or Codex in the same session you had on your laptop.

The Workflow

The idea is that your VPS becomes your dev machine. Your laptop and phone are just terminals into it. Now sometimes if I know I won’t be going outside I’ll just run Claude Code / Codex locally, but if I’m going to be outside I’ll use the VPS.

On your laptop:

  1. SSH into the VPS: ssh dev@100.x.x.x
  2. Start or attach to tmux: dev
  3. Clone your repo and run Claude Code / Codex there
  4. When you need to leave, just close the terminal (or detach with Ctrl+b then d)

On your phone:

  1. Open Tailscale and connect
  2. Go to Termius, connect to the same VPS
  3. Type dev to attach to the same tmux session
  4. You’re now in the exact same terminal, same Codex conversation, same everything.

Tips

  • Disable key expiry for your VPS in the Tailscale admin console
  • The 2 vCPU / 2-4GB RAM tier is plenty for most agent work

Disclaimer

I’m not an expert in security, so please be careful with your setup. This whole process was me figuring things out and asking ChatGPT when I needed help.