CNPG cluster (component)
A Kustomize component that turns "this app needs Postgres" into a single line in the app's kustomization.yaml. Pulls in a CloudNative-PG Cluster resource pre-tuned for the homelab's conventions — Longhorn-encrypted PVCs, k8up-driven snapshots, and a per-app pg_dump backup command.
What it composes
Per app, the component lands a Cluster resource named <app>-db in the app's namespace, with:
- One primary, one replica by default — enough for survival of a single-node outage; tunable per app via the patch.
- Longhorn-encrypted PVC for the data directory (sized via the app's patch).
k8up.io/backupcommand: pg_dumpannotation so k8up snapshots a logical dump rather than the filesystem.k8up.io/file-extension: .sqlso the snapshot is restorable with plainpsql.- Sensible defaults for
postgresql.parameters(shared_buffers, work_mem, etc.) tuned for small homelab workloads.
The CNPG operator itself lives in platform/cloudnative-pg; this component is the per-app instance of its Cluster CRD.
How an app uses it
# k8s/apps/talos/<app>/kustomization.yaml
components:
- ../../../components/talos/cnpg
patches:
- target:
kind: Cluster
name: app-db
patch: |
- op: replace
path: /spec/storage/size
value: 20Gi
The app overrides whatever defaults don't fit — usually storage size and replica count. Anything not overridden takes the component's value.
Why pre-tune in a component, not per-app
- Consistency. Every Postgres in the homelab is shaped the same way; backups, encryption, and replica counts don't drift app by app.
- One place to update conventions. When a new CNPG version changes its
ClusterAPI, the component absorbs the change once. - Backup wiring lives with the database, not the app. The
k8up.ioannotations are part of the component, so an app that uses the component automatically gets the rightpg_dumpsnapshot path.
Operational notes
- Restoring is the postgres-restore runbook —
kubectl execinto the primary and stream the dump throughpv. The path is identical regardless of which app's database is being restored, thanks to the component's uniform shape. - An app that needs no Postgres just doesn't include this component. There's no global default — opt-in only.
- Removing the component from an app's
kustomization.yamldeletes theClusterresource on next reconciliation — which deletes the PVC, which destroys the database. Restore-from-snapshot is the only recovery; warm tier covers it but RPO is one backup cycle.
Cluster Deployment
- Talos
- Edge
Depends on
Depends on