How I Manage My Homelab Remotely

A friend asked how I manage the Proxmox cluster when I am away from home. The short answer is Tailscale and SSH. The more useful answer is that remote access and remote changes are two different things here, because having a shell from anywhere is convenient and also a very efficient way to break the house from a train.

Getting onto the network

Nothing in the lab needs a public SSH port. I run Tailscale on the devices I carry and on the machines I need to reach. Once my device joins the tailnet, the lab behaves as though I am on another private network attached to it. I can use the same stable Tailscale addresses wherever I happen to be, without forwarding port 22 through the router or keeping track of my home IP address.

Tailscale is doing two separate jobs underneath that fairly boring experience. Its coordination service authenticates the devices, exchanges their public keys and tells them how to find each other. The actual connection is an encrypted WireGuard tunnel between the devices. It tries to make that connection directly through NAT; when that is impossible, encrypted packets go through a DERP relay instead. The relay can move the packets but cannot decrypt them.

That split is why this feels less like dialing into a traditional VPN concentrator. Tailscale arranges the introduction, then the traffic normally goes straight from the device in my bag to the machine at home.

SSH from Termius

For a terminal I use Termius. Each Proxmox host and the few guests I might need to inspect are saved there with their Tailscale address and SSH user. I connect Tailscale first, open Termius, and use ordinary key-based SSH. Termius is the client, Tailscale is the route, and OpenSSH on the server is still the thing authenticating the session.

That shell is mostly for looking. I use it to check a service, read logs, confirm disk space, or work out why an alert fired. If the fix changes how the lab is meant to be configured, I do not leave the answer sitting in shell history.

Changes still go through Forgejo

The infrastructure lives in git on my self-hosted Forgejo instance. A change goes onto a branch and into a pull request, even when I am doing it remotely. Forgejo Actions runs the OpenTofu plan on the PR. I read that output, approve the PR, and merge it. The merge to main is what lets the runner apply the change to Proxmox.

flowchart LR
    device["Laptop or phone"] -->|"Tailscale"| lab["Private lab network"]
    device -->|"Termius + SSH"| inspect["Inspect hosts and guests"]
    device -->|"Open and approve PR"| forgejo["Forgejo"]
    forgejo -->|"tofu plan"| review{"Plan looks right?"}
    review -->|"merge"| apply["tofu apply"]
    apply --> proxmox["Proxmox cluster"]

The approval is deliberately still there. Remote access removes the distance, but it does not make a destructive plan less destructive. The PR leaves a diff, the plan shows what OpenTofu thinks it will do, and the commit gives me something to revert. It also means the configuration in git remains the source of truth instead of slowly diverging from whatever I typed into a terminal six months ago.

There are two plain failure cases. If the home internet is down, I cannot get in. If the whole cluster is off, software running on the cluster cannot turn it back on. Tailscale solves reachability through an awkward residential network. It does not solve power cuts, dead hardware, or my ability to approve a bad plan from several hundred miles away.

So the mechanism is small: Tailscale provides the private encrypted path, Termius carries SSH over it, and Forgejo turns intended changes into a reviewed plan before the runner touches Proxmox. I can diagnose from anywhere. Changes still have to take the long way round.

Discussion