Use Determinate Systems installer
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | \
sh -s -- installcd /etc
curl https://github.com/jodosha/dotfiles/archive/refs/heads/master.zip -O nix-darwin.zip
unzip nix-darwin.zipcd /etc/nix-darwin
nix run nix-darwin/master#darwin-rebuild -- switch
darwin-rebuild switchnix-remote-builder
nix flake update
rebuildTurn a fresh Hetzner (Debian/Ubuntu) box into a secondary dev machine — Nix +
Home Manager, hardened SSH, ready to run Claude in tmux and drive it from the
Claude iOS app via /remote-control.
As root on a fresh Ubuntu 24.04 box (or as cloud-init user-data):
curl -fsSL https://raw.githubusercontent.com/jodosha/dotfiles/master/scripts/provision-vps.sh | sudo bashThe script is idempotent — re-run it any time to converge to the latest
dotfiles. Configure via env vars (PROVISION_USER, SSH_PUBKEY /
SSH_KEYS_URL, DOTFILES_REPO, DOTFILES_REF, SWAP_SIZE, SSH_PORT); see
the header of scripts/provision-vps.sh.
Two steps by hand after provisioning:
ssh jodosha@<box>
# 1. Register this box's key on GitHub (Verified signatures + SSH push):
gh auth login
gh ssh-key add --type signing ~/.ssh/github.pub
gh ssh-key add --type authentication ~/.ssh/github.pub # optional, for SSH push
# 2. Drive Claude from your phone:
tmux
claude # complete the browser OAuth login
/remote-control # register this session, then open the Claude iOS appCommits are SSH-signed with a dedicated, passphrase-less per-machine key at
~/.ssh/github (also usable for SSH push). Until you register it above, signed
commits read Unverified on GitHub.
Portable Claude Code config is versioned in misc/claude/ and deployed by Home
Manager on both the Mac and the VPS:
~/.claude/{profiles,scripts,agents,commands}— symlinked frommisc/claude/.~/.claude/settings.json— generated per-OS frommisc/claude/settings.jsonplus the OS-awaresandboxinhome.nix, and repo-authoritative (rewritten on everyrebuild). Edit settings inmisc/claude/settings.json(orhome.nixforsandbox); use a project.claude/settings.local.jsonfor local overrides (git-ignored, deep-merged over the global, never clobbered).
Regenerable / not versioned — rehydrate by hand: gstack (its own installer +
/gstack-upgrade), the plugins/ tree (re-fetched from the settings seed),
projects/, ~/.claude.json (gbrain MCP), and .credentials.json (interactive
claude OAuth). Remote MCP (atlassian/sentry) authenticate via /mcp.