CS-01
Homelab
A self-hosted platform on a single Proxmox host, run like production, with media, photo backup and finance tooling, all changed through code instead of clicks.
Draft. This write-up is in progress and has not been fact-checked against the real system.
Scope note. This write-up stays at the architecture level on purpose. It contains no addresses, hostnames, ports or network layout of the real system.
The problem
I wanted a place to run the software I rely on every day (a media library, photo backup and my own finance tooling) without handing that data to third-party services, and without it turning into a pile of hand-tuned machines that only I could remember how to fix.
The constraint I set myself: treat it like a small production environment. That means anything running should be reproducible from a repository, recoverable from backup, and changeable without logging in and improvising.
Architecture
One physical host runs Proxmox. Everything else is a guest on top of it.
Layers
- Hypervisor. Proxmox hosts the guests. Splitting workloads across guests keeps a failure or a bad upgrade in one service from taking the others down.
- Services. Each concern (media, photo backup, finance tooling) is its own Docker Compose stack with its configuration in the repository.
- Access. Outside access goes through a Cloudflare Tunnel, so nothing needs an inbound port opened on the home network.
- Backups. Photos and finance data are the irreplaceable parts, so they are treated differently from the media library, which can be re-acquired.
How changes are made
Every change goes through the repository, driven by a Makefile that wraps
the bash and docker compose commands:
- Edit the compose file or script in git.
maketargets validate and apply it (the same commands every time).- The commit message records why the change was made.
The rule that matters most is that there are no “just this once” manual edits on a guest. If the host were lost, the repository plus backups are enough to rebuild it.
Decisions and trade-offs
| Decision | Why | Cost |
|---|---|---|
| Docker Compose rather than Kubernetes | One host, one operator. Compose is enough and I can debug it at 11pm. | No automatic multi-node failover. |
| Bash + Make rather than a config-management tool | Few moving parts; readable by anyone. | I enforce idempotency by discipline, not by the tool. |
| Tunnel instead of port forwarding | Smaller attack surface; no public IP exposure. | Depends on a third party being up. |
What I’d do next
- Document and rehearse a full restore from backup.
- Add monitoring so failures are noticed before I notice them.
What this shows
Treating a personal system with production habits (reproducibility, backups, change control) and being able to explain each trade-off.