The IaC system for my homelab and other devices.
vps0is a cloud VPS that uses Docker Compose to run public-facing services likeapps.obtainium.imranr.devand tunnel some requests through tosrv0.srv0is a lightweight home server that uses Kubernetes (K3s) to run personal services like Immich.bigpcis a gaming PC that also serves as a Kubernetes worker node for GPU-accelerated workloads like Ollama.pcis a laptop that runs Syncthing (via Docker Compose) to sync files tosrv0.rpiis an SBC that streams a live camera feed to Frigate onsrv0.
- Infrastructure as Code: Everything should be declarative and automated, using standard tooling wherever possible. Custom scripts should be minimal and only where necessary.
- Security: As the codebase is public and the system runs public-facing services containing highly personal data, security must be taken seriously. To that end:
- Authelia SSO guards every service that needs it.
- CrowdSec automated threat response guards all public services.
- Geoblocking is used for services that do not need to be globally accessible.
- Network policies are used in the
srv0Kubernetes stack to ensure that pod-to-pod communication is only allowed where necessary. - WireGuard key pairs (as opposed to symmetric token-based encryption) protect the public-exposure tunnel between
srv0andvps0; each peer authenticates with its own key, preventing certain kinds of MITM attacks. - The Principle of Least Privilege is applied to containers, with elevated privileges and root runtime user only allowed where necessary. Host devices are granted as Kubernetes device-plugin resources (via the generic-device-plugin) rather than
privileged: true. - Comprehensive Monitoring and Alerting is done using Alloy + Prometheus, Loki, Grafana, Ntfy.sh + Logtfy, Headlamp, Dozzle, and Uptime Kuma.
- Falco flags suspicious activity on K3s nodes.
- A Honeypot (Opencanary) is used to discover intruders.
- Regular update checking is done via Renovate: a six-hourly Renovate-only run opens PRs and auto-merges non-major app updates after their test gate, while every Infra digest/chart PR is a manual rollout gate.
# Install prerequisites on every machine
bash scripts/prereqs.sh
# Create the gitignored config tree (never overwrites existing files).
# On srv0, --detect fills MY_UID/GPU_PROFILE/HA_CONBEE/HA_BLUETOOTH.
bash scripts/init-config.sh srv0 --detect
bash scripts/init-config.sh vps0
# Fill config/VARS.env, values/compose envs, Authelia users/rules, and the
# optional vps0 agent config. The explorer Configuration tour covers the full surface.
bash scripts/validate.sh srv0
bash scripts/validate.sh vps0
# Deploy one target; srv0 uses Helm, the rest use the Compose wrapper.
bash scripts/deploy.sh srv0
bash scripts/deploy.sh vps0
bash scripts/deploy.sh pc
# Or run Compose directly through the wrapper (env files, machine facts,
# private overlay, profiles, and vps0 Authelia render are automatic).
bash scripts/compose.sh vps0 up -d
bash scripts/compose.sh vps0 logs -f authelia
# Run Renovate manually (the in-cluster jobs do this on a schedule) — machine-local
bash scripts/renovate.sh [apps|infra|all|clear-cache] [--dry-run]The architecture, request path, public edge, WireGuard, apps/data, operations, configuration, first boot, and maintenance walkthroughs live in the guided explorer app in explorer/. It requires Node.js 18+ and npm.
cd explorer
npm install # first run only
npm run devOpen http://localhost:4173/. For a production build:
npm run build
npm run previewThe explorer is the documentation for this repo; AGENTS.md remains the contributor/operations guide.
The guided explorer is the documentation: start with the Start here tour, then use the topic tours for the public edge, WireGuard, apps/data, operations, configuration/decisions, first boot, and maintenance. Contributor and agent rules remain in AGENTS.md.
Note that while LLMs are used in development, the LLM isn't the one putting its data on the line. It is just a tool and is used like one.