Every SaaS I’ve ever loved eventually did one of three things: raised its price, got acquired, or quietly changed the terms under which it held my data. That’s not a betrayal — it’s just the incentive gradient. The fix isn’t outrage. It’s ownership.
The actual argument
People frame self-hosting as a trust problem, like it’s about not liking Google. It isn’t. It’s about latency of control: when the thing you rely on lives on someone else’s roadmap, you wait. When it lives on yours, you don’t.
It’s less work than it looks
The homelab internet loves a 40-service Kubernetes cluster. You don’t need it. A single small box and a compose file gets you surprisingly far:
services:
app:
image: ghcr.io/me/app:latest
restart: unless-stopped # survive reboots
env_file: .env # secrets stay on the box
ports:
- "127.0.0.1:8080:8080" # only expose behind a reverse proxy
The two highlighted lines are 90% of “production readiness” for a personal app: restart on failure, and keep secrets on the machine instead of in a dashboard. When you outgrow one service, you don’t rebuild — you drop another compose file onto the same box and the same shared network, and put it behind one reverse proxy that already handles TLS for everything. The complexity stays additive.
What I actually run
One small box. One Docker network. A folder of compose files grouped by what they do. A quick tour of the parts I actually enjoy:
- Convex and PocketBase — self-hosted backends, so the little apps I build get a real database, auth, and file storage without renting anyone’s cloud
- Jellyfin + the *arr stack — a media library that catalogs and fetches itself, end to end
- AdGuard Home — ad and tracker blocking for every device on the network, done once at the DNS instead of app by app
- Umami — analytics and uptime that answer to me, not to an ad network; Umami is counting this page right now
- Twingate — zero-trust access to all of it, so almost nothing needs a public port open at all
…plus a couple of apps I wrote myself running on the same box as everything else.
Is that more than anyone needs? Absolutely. It grew from one service into a hobby, and I’ve made peace with that. But look at the shape: nothing here is a cluster. Each piece was a compose file that fixed one specific itch, dropped next to the last one. You are never forced to level up all at once — which is exactly why “you don’t need Kubernetes” stays true even when you end up running sixteen of these.
The catch
You become the on-call engineer. Updates, uptime, and backups are yours now, and “it’s down” has no support line to call. But that trade — a little ownership for a lot of control — is one I’ll take every time.
If you’ve been meaning to try it, pick one boring service this weekend. That’s the whole on-ramp.