Homelab Infrastructure

A working homelab is the cheapest possible production environment. This one runs Kubernetes on Proxmox/Talos with two-loop GitOps, 30+ Docker services, and the nginx that's serving you this page.

You are reading this page because of this stack. The nginx config that routes anthonyr.com is one of the conf files in the same git repo this HTML lives in. Deploy is git pullnginx -t → reload — deploy-by-commit, with the config test gating the reload.

By the numbers

40+
Docker Compose stacks across 3 hosts
17+14
VMs + LXCs on the Proxmox host
2
GitOps reconciliation loops (OpenTofu + Flux)
nginx -t
gates every deploy before reload

Kubernetes layer

Data-driven K8s infrastructure on Proxmox/Talos Linux with two-loop reconciliation:

It's run as a patterns platform — the place to keep the GitOps muscle memory. Production homelab workloads deliberately stay on Docker Compose; knowing when not to reach for Kubernetes is part of the job.

Docker Compose layer (Dockge-managed)

Services that don't need to live in K8s run as Docker Compose stacks orchestrated by Dockge. A sample of what's running:

AnythingLLMDocument Q&A
n8nWorkflow automation + scheduled AI
Prometheus + GrafanaMetrics + dashboards
LokiLog aggregation
ELK StackBuild/release/test metrics
GuacamoleBrowser-based remote access
HeimdallService dashboard
Speedtest trackerISP performance over time
TailscaleMesh VPN
Plex / *arrMedia
Uptime KumaSynthetic monitoring
Proxmox metricsHypervisor exporter

Nginx + this site's deploy loop

The entire nginx config tree is a git working tree, and a single script (syncAndRestart.sh) runs the deploy sequence:

The pull is kept a deliberate, attended step rather than an unattended auto-pull cron — a supply-chain safeguard, so a compromised or bad commit can't reach the public edge without a human in the loop. The site you're reading is colocated in the same repo as the nginx config: commit, push, run the deploy, and the config test either passes or the old config keeps serving. The same pattern quietly fronts a whole menagerie of other vhosts — self-hosted apps, admin dashboards, media and automation services, and a handful of personal sites — each terminated and reverse-proxied through the same battle-tested include stack.

AI SRE — the observability brain

Logs from five hosts ship into Loki; a FastAPI service asks a Claude model to read them like an on-call SRE and writes prioritized incident reports on a cron. The non-obvious part is a persistent issue-ledger that gives the LLM cross-run memory — every report tells me what's new, still ongoing, or newly resolved, instead of re-flagging the same warning forever. False-alarm guards, push alerts with P1 escalation, bounded token cost. Full writeup →

Docs-as-code — the source of truth

The whole homelab is documented in one git repo, and the documentation keeps itself honest: collector scripts SSH into each host and regenerate inventory snapshots deterministically, so git log over the generated tree is a live infrastructure drift ledger. A weekly cron on the Proxmox host re-runs the collectors and auto-commits any drift. Every host page carries a hard-death rebuild runbook; secrets are structurally excluded by fail-closed sanitization that aborts if key material survives redaction. The point: infrastructure documented well enough that an AI agent — or a stressed human at 3am — can operate it.

Ansible (the boring part)

Playbooks for system patching, reboot management, hardware inventory, and historical data collection across the homelab fleet. Not glamorous; the kind of automation you only notice when it's missing.

Why it matters (the wedge)

I run my own infrastructure the way real infrastructure runs: idempotent provisioning, declarative reconciliation, encrypted secrets in source control, observable failures with paging. The homelab is not a toy — it's the reproducibility lab for the patterns that ship at SanMar.