Self-hosted infrastructure
Homelab
A Proxmox host under my desk running the git remote, the storage and the services the rest of this work depends on.
- Proxmox
- ZFS
- LXC
- Cloudflare Tunnel
- Tailscale
- Gitea
- LXC & VMs
- ~10
- Storage tiers
- 3
- GB RAM
- 32
Why run your own
Most of what I build needs somewhere to live: a git remote, a database, a place to put files, a staging box. Renting all of that gets expensive quickly, and more to the point, renting it means never learning what happens when it breaks.
So it runs here, on a machine I built, that I am responsible for.
The host
A bare-metal Proxmox hypervisor on modest hardware — a Ryzen 3 3100, 32 GB of RAM and a GTX 1650. Around ten LXC containers and virtual machines in continuous use.
Storage is tiered deliberately across three drives rather than thrown into one pool:
- an NVMe boot and LVM volume for the hypervisor and anything latency-sensitive
- a two-disk ZFS mirror for data that must survive a drive failure
- a secondary ZFS pool for bulk storage, where capacity matters more than redundancy
ZFS is doing the work that matters here: checksums, snapshots, and the ability to notice corruption rather than faithfully serving it back.
What runs on it
- Gitea at
git.shreyaskamat.in— the source-of-truth remote for client and personal work. This is the one that changed how I work; a git host I control means private repositories are free and the history is genuinely mine. - TrueNAS as the storage backend
- Immich for photo management
- Firefly III, managing a racing team's finances — the instance other people actually depend on
- a Windows 11 VM with full GPU passthrough, streaming games over Sunshine and Moonlight, and handling hardware-accelerated transcoding
GPU passthrough was the hardest thing here by some distance. Handing a physical card to a guest means fighting IOMMU groups, driver binding, and a host that would rather keep the GPU for itself.
Getting to it
Cloudflare Tunnel exposes the services that need to be public, under my own domain, with no ports forwarded and no static IP. Tailscale provides a mesh for everything that should stay private — which is most of it. Nginx handles reverse proxying, with Let's Encrypt certificates renewing themselves.
The rule I hold to: nothing is exposed publicly unless there is a reason it must be.
What it actually taught me
The interesting part of running your own infrastructure is not the setup. It is the failures, because they are the ones nobody has written a tutorial for:
- Container boot-order and NFS dependency races — services starting before the storage they mount is ready, which fails only sometimes and only after a reboot.
- Storage mount misconfiguration that looked fine until something wrote to the wrong pool.
- GPU passthrough conflicts between host and guest claiming the same device.
Each of those was debugged rather than reimaged. That is the whole value of the exercise: the temptation is always to flatten it and start again, and the learning is entirely in not doing that.
The honest limitation
It is one host. There is no high availability, no off-site replication beyond what matters most, and a power cut takes everything down at once. That is an acceptable trade for a homelab and would be unacceptable for anything with real users — which is precisely why the things other people depend on are the ones I think hardest about.