Homelab
What actually exists, and where. Three machines, a Tailscale mesh, and everything running on top of it.
Internet in, Tailscale everywhere else.
Only one machine is exposed to the internet. Everything else is reachable exclusively over the tailnet — including from that one public machine, which is how a public request ends up served by a box sitting at home without that box ever opening a port to the world.
- Machines
- 3
- Public endpoints
- —
- Checked
- —
What am I actually running this on?
- Role
- Virtualization / compute · storage
- CPU
- Intel Xeon E5-1650 v4 @ 3.60GHz
- Memory
- 64GB RAM
- Storage
- 2 × 8TB
- OS
- OpenMediaVault
Why it's here. The home box everything else depends on. Not public-facing, so it doesn't need to survive being on the internet — just being at home. Hosts the CI runners, so builds run on hardware I own with no third-party rate limits, plus everything that wants real disk: photos, media, and the metrics for the rest of the lab.
- Role
- Edge / public ingress
- CPU
- 2 vCPU
- Memory
- 4GB RAM
- Storage
- 40GB
- OS
- Ubuntu
Why it's here. The only node exposed to the internet. Runs the reverse proxy and every public-facing service — this site included. Because it also sits on the tailnet, it can forward traffic to services running on thunkstation without exposing thunkstation directly.
- Role
- Compute · being replaced
- CPU
- 2 vCPU
- Memory
- 4GB RAM
- Storage
- 40GB
- OS
- Ubuntu
Why it's here. Private automation box, reached over Tailscale (and Telegram for specific jobs) rather than the open internet. Currently running openclaw. Being replaced.
Grouped by purpose, not by machine.
Most of these don't need an essay. A few do, and get one.
- Tailscale private mesh — every node talks to every other node directly
- Nginx Proxy Manager public ingress + TLS termination · xpekatt-hel
The only door open to the internet. Routes by hostname — adding a service means adding a proxy host entry and pointing DNS at the VPS.
- Gitea + runners git hosting, CI/CD, container registry · thunkstation
A push triggers a workflow, the runner builds and pushes tagged images, deploy hosts pull. The full loop stays on hardware I own — see Under the Hood for how that plays out for this site specifically.
- openclaw SSH / Telegram automation · claw-hel, being replaced
- Prometheus scrapes and stores metrics · thunkstation
- Grafana dashboards on top of Prometheus · thunkstation
- node-exporter host metrics, one instance per machine
- status.dev.xplwd.com external uptime check for every public endpoint
- Immich self-hosted photo library · thunkstation
Occasional gotcha: updates sometimes need a database migration before the new container will start. Read the release notes first, or it looks broken when it's just waiting.
- Jellyfin media server · thunkstation
- goonk.se this site · xpekatt-hel
- f1-dashboard, PSBloggen, Delve — and 22 more games, tools, and site infrastructure like analytics · xpekatt-hel
Full catalog on /projects.
How does goonk.se get deployed onto this? Follow a deployment →
Not self-hosting evangelism. Just the actual tradeoffs.
I know where the data lives, and nobody can change the pricing tier on hardware sitting in my own home.
Sometimes cheaper than the equivalent managed services. Definitely not if I calculate my own time at any reasonable rate.
A suspiciously large percentage of this exists because I wanted to know if I could make it work, not because it was the efficient choice.
Fewer things disappear because a platform changed its terms, its API, or its AI policy — I've already noped out of one for exactly that reason.
When it breaks, the support department is also me, usually at an inconvenient hour.