Skip to content
Mohd Khizer Hayat

← All work

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.

Homelab architecture A Proxmox host contains guests that run Docker Compose stacks for media, photos and finance. A git repository drives changes through Make. A Cloudflare Tunnel provides outside access without opening inbound ports. Proxmox host Guests (VM / container) Media Photos Finance Backups Git repo make + compose Cloudflare Tunnel
Simplified. Stacks are isolated by service; the tunnel is the only path in from outside.

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:

  1. Edit the compose file or script in git.
  2. make targets validate and apply it (the same commands every time).
  3. 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.