The Stack
What a mature self-hosted homelab looks like — 25+ services on local metal
This is my actual infrastructure. Not a reference architecture or a planning document — the real thing, running on Proxmox in Hamilton, Ontario. I'm documenting it because most self-hosting guides show you either a single container or an enterprise deployment. Here's what the middle looks like after years of iteration.
The Foundation
Proxmox VE on commodity hardware. VMs and LXC containers. Nothing exotic — the point is that you can replace any piece of this with what you have. Proxmox is free, runs on anything with a CPU and enough RAM, and gives you a web interface for managing your fleet.
Everything runs in Docker containers managed by Docker Compose. Each service gets its own directory, its own compose file, its own data volume. This isolation means I can update, restart, or debug one service without touching the others.
The Gateway
Traefik as the reverse proxy. Every service is reachable by domain name with automatic TLS via Let's Encrypt. Traefik watches Docker labels to discover new services — deploy a container with the right labels and it's automatically routed. No nginx config files to edit by hand.
Crowdsec as the community-driven WAF. It reads Traefik access logs, detects attack patterns, and shares threat intelligence with other Crowdsec nodes. Think fail2ban but collaborative and aware of application-layer attacks. See Traefik + Crowdsec for the setup.
WireGuard for remote access. No port forwarding, no exposed services. I connect to my network from anywhere through an encrypted tunnel. The only publicly exposed ports are 80 and 443 through Traefik.
The Services
Security & Identity
- Vaultwarden — Self-hosted Bitwarden. Passwords, TOTP, secure notes. The first service I tell everyone to self-host.
- Crowdsec — Intrusion detection and community threat sharing.
Code & Development
- Gitea (port 4455) — Self-hosted Git. All my repositories, CI runners, issue tracking. My code doesn't live exclusively on someone else's platform.
- The Samaritan Portal (port 3304) — This site. SvelteKit, built and served by nginx in Docker.
Media & Knowledge
- Plex — Media server. My library, my rules, no algorithm deciding what I should watch.
- Navidrome — Music streaming. Subsonic-compatible, works with any Subsonic client.
- Audiobookshelf — Audiobook and podcast server with progress tracking.
- Kiwix — Offline Wikipedia and other reference archives. The entire English Wikipedia runs locally.
Home & Automation
- Home Assistant — Home automation without cloud dependencies. Lights, sensors, climate — all local.
AI & Inference
- Ollama (10.10.20.19) — Local LLM inference. Multiple models running on local GPU. No tokens sent to external APIs for private queries.
- Bifrost (port 3360) — OpenAI-compatible inference gateway. Routes requests to the right model backend.
Web Properties
- Souveraine Website (port 3303) — souveraineai.com
- Casey Tunturi (port 3300) — caseytunturi.com
- RedFlag (port 3302) — redflag.wiuf.net
Utilities
- PrivateBin — Encrypted pastebin. Share text without a third party reading it.
- Deluge — Torrent client with web interface.
The Patterns
One service, one directory, one compose file. Resist the temptation to put everything in a single docker-compose.yml. At 25+ services, monolithic compose files become unmanageable.
Labels over port mapping. Use Traefik labels on containers instead of exposing ports directly. Let the reverse proxy handle routing.
Volumes, not bind mounts, for persistent data. Unless you need direct filesystem access (like serving static files), named volumes are cleaner.
Restart policies matter. restart: unless-stopped for everything. If the host reboots, your services come back. If you explicitly stop a container, it stays stopped.
Back up the data directories. The compose files are replaceable — they're in Git. The data volumes are not. Back them up. Test restores. I use a combination of local snapshots and encrypted off-site copies.
See Docker Patterns for more operational detail.
Why this and not the cloud
This entire stack runs on hardware I own. The electricity bill is real. The maintenance is real. But the trade-off is clear: none of these services can be taken from me by a vendor decision, a pricing change, or an acquisition. My passwords, my code, my media, my home automation, my AI inference — all on my metal.
That's the stack. It took years to get here. Start with one service and grow.