This repo manages the current homelab as:
k3son three bare-metal control-plane/storage nodes- GitOps-managed cluster manifests under
k3s/cluster/ - Ansible-managed node bootstrap and lifecycle under
k3s/ansible/ - separate edge automation under
edge/
The old Docker Compose stacks/ tree is no longer the primary deployment model. Some content there is still useful as migration history or for a small number of legacy workloads, but the active platform is the k3s/ tree.
homelab-infra/
├── README.md # repo overview and doc index
├── docs/ # historical notes and migration leftovers
├── edge/ # edge host automation and docs
├── k3s/ # active cluster code, runbooks, and app manifests
├── stacks/ # mostly legacy compose stacks and migration artifacts
└── renovate.json # update automation for live edge/k3s assets
This is the main platform.
k3s/ansible/- host inventory
- node bootstrap
- k3s install and upgrade playbooks
- Longhorn disk prep
- etcd-to-Garage backup configuration
k3s/cluster/- Flux-managed cluster manifests
- infra components such as Traefik, Longhorn, MetalLB, cert-manager
- app manifests split into
longhorn-backed/andnas-attached/
k3s/docs/- operational runbooks and recovery docs
This holds the separate edge host automation, including:
- Caddy config deployment
- edge support services
- dedicated step-ca bootstrap for ingress PKI
This is no longer the default deployment path. Keep it as:
- migration history
- reference configs from the pre-k3s setup
- a place for anything that still intentionally runs outside the cluster
If a service is active in k3s, prefer the docs and manifests under k3s/ over anything under stacks/.
Use Ansible for node preparation and K3s lifecycle:
- inventory: k3s/ansible/inventory/hosts.yaml
- shared defaults: k3s/ansible/group_vars/all.yaml
- main runbook: k3s/docs/README.md
Use Flux-managed manifests under k3s/cluster/ for:
- core infra
- storage classes
- ingress
- applications
- encrypted Kubernetes secrets
SOPS is used in two contexts:
k3s/cluster/.sops.yamlfor in-cluster Kubernetes secretsk3s/.sops.yamlandedge/.sops.yamlfor Ansible-side encrypted vars
Relevant docs:
- k3s/docs/README.md: primary K3s setup and operations runbook
- k3s/docs/backups.md: current backup coverage, restore procedures, and gaps
- k3s/docs/adding-nodes.md: adding or replacing nodes
- k3s/docs/ingress.md: ingress and traffic flow
- k3s/docs/flux-debugging.md: Flux troubleshooting
- k3s/docs/secrets.md: SOPS + age workflow
- k3s/ansible/README-etcd-backups.md: playbook-level etcd backup setup
- k3s/docs/backups.md: operational restore procedures and current backup status
- k3s/cluster/apps/longhorn-backed/README.md: Longhorn-backed app conventions
- k3s/cluster/apps/nas-attached/README.md: NAS-attached app conventions
- edge/docs/README.md: edge automation overview
- edge/docs/step-ca.md: dedicated step-ca notes
Examples of workload-level docs that matter during migrations or restore work:
- k3s/cluster/apps/longhorn-backed/keycloak/README.md
- k3s/cluster/apps/nas-attached/music-stack/navidrome/README.md
- stacks/moved-to-k3s/keycloak/README.md
Current state:
- embedded etcd snapshots are configured on the k3s servers and replicated to Garage
- Longhorn recurring backup-to-Garage is live and restore-tested
- application-consistent backup jobs are live and validated for Mattermost, Keycloak, Nextcloud, Firefly, and BookStack
- Home Assistant uses its native backup workflow, with Longhorn retained as a storage fallback
- NAS-attached datasets still require Unraid-side snapshot and offsite replication policy outside the cluster manifests
Read k3s/docs/backups.md before making storage or recovery changes. That file is the source of truth for current backup coverage, artifact locations, and restore procedure.
Historical notes remain under:
- docs/migration-notes.md
stacks/
Treat them as reference material unless a service is still intentionally running there.