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 + Mimir, Loki, Grafana, Ntfy.sh + Logtfy, Headlamp, Dozzle, and Uptime Kuma.
- A Honeypot (Opencanary) is used to discover intruders.
- Regular update checking is done via Renovate (updates are applied manually to avoid unplanned changes).
# Install prerequisites
bash scripts/prereqs.sh
# Create your configuration from the templates (values.yaml for k3s, compose.env
# for compose, plus extra files like certs and the Authelia users DB):
cp -r targets/<target>/config_template config/<target> # then fill in real values
cp config_template/VARS.env config/VARS.env # then fill in
# Validate your configuration
bash scripts/validate.sh <target>
# Deploy k3s
bash scripts/kubeconfig-unlock.sh # unlock kubeconfig (so non-sudo can read it temporarily); run in another terminal
helm upgrade --install srv0-base targets/srv0/k3s-base -n base --create-namespace \
-f targets/srv0/k3s-base/values.yaml -f config/srv0/values.yaml
helm upgrade --install srv0-apps targets/srv0/k3s-apps -n apps --create-namespace \
-f targets/srv0/k3s-apps/values.yaml -f config/srv0/values.yaml
# Deploy compose
# vps0 (VARS-driven, with a config env):
docker compose --env-file config/vps0/compose.env --env-file targets/vps0/compose/.env \
-f targets/vps0/compose/compose.yaml \
[-f targets/vps0/compose/compose.private.yaml] up -d --remove-orphans
# srv0 (public-exposure client sidecar; config env only):
docker compose --env-file config/srv0/compose.env -f targets/srv0/compose/compose.yaml up -d
# pc/bigpc/rpi (machine facts only — the project-dir .env auto-loads):
docker compose -f targets/<target>/compose/compose.yaml up -d
# Check for updates (opens Renovate PRs on GitHub) — machine-local
bash scripts/renovate.shDetailed documentation lives 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.