This repository is public, so it documents behavior without publishing the live deployment map. Credentials, account names, addresses, public hostnames, ports, interface names, and hardware identifiers are deployment data rather than reusable documentation.
Tracked configuration uses variables or documentation-only examples. Copy
ansible/inventory/group_vars/homelab/site.yml.example to the ignored
site.yml and fill it from the private operational record before running
Ansible. The deployment renders site-specific monitoring configuration under
the ignored .generated/ directory.
Real .env files also remain ignored and are supplied manually. Ansible checks
their presence and permissions but never reads or creates their values. Exact
ingress routes and endpoint inventories belong in the private operational
record, not in public documentation.
Direct Compose commands require the non-secret interpolation keys shown in the
tracked .env.example files. Routine deployment uses
ansible/playbooks/deploy.yml, which injects the private site values and
renders the monitoring override before Compose validation.
Encrypted secrets are not committed to this public repository. SOPS with age recipients may be reconsidered for a separate private operations repository if manual restoration becomes burdensome. That design would need multiple recovery recipients and a tested offline restore before replacing the current manual secret restoration process.
Central identity is provided by a self-hosted lldap + Authelia stack (see
docs/identity.md). Authelia is the OpenID Connect provider with TOTP MFA for
Audiobookshelf, Kavita, Actual Budget, Grafana, Tandoor
Recipes, and SparkyFitness; lldap is the single user directory.
Audiobookshelf, Kavita, Actual, Tandoor Recipes, and SparkyFitness keep their
local login as a fallback, so an Authelia outage never locks those apps. Grafana is
SSO-only (its login form is hidden); its fallback is a break-glass local admin
that an operator re-enables in the database. Plex keeps Plex authentication;
request apps keep Plex authentication plus local recovery. Infrastructure retains
local console and administrator recovery.
Only Authelia is exposed to the internet (through the Cloudflare tunnel); lldap
and redis are internal-only. Every secret is read from files on the server and
none are committed. The stack's data lives under ${APPDATA} and is covered by
restic. Backup, session revocation, and local recovery accounts follow the same
file-based, restic-protected model as the rest of the fleet.
WireGuard on the router is the preferred path for remote access to private operator services. Public ingress remains limited to services with an active remote-user requirement.
- Keep operator services LAN- or VPN-only and retain their built-in login.
- Use unique application credentials and integration keys, and rotate them independently after compromise.
- Do not add proxy authentication while applications remain directly reachable on the LAN; it would be bypassable and complicate API clients.
- Review public tunnel routes periodically and remove unused routes.
- Preserve local recovery for the router, hosts, SSH, and other infrastructure.