MongoDB (component)
A Kustomize component for the apps that genuinely need a document store rather than relational storage. Drops a single-replica MongoDB StatefulSet into the app's namespace, with the same backup wiring as the cnpg component — Longhorn-encrypted PVC, k8up-annotated for the warm tier.
The homelab's default database is CNPG Postgres. MongoDB exists only for apps whose upstream genuinely speaks MongoDB and where a translation layer would be a worse tradeoff than running another datastore.
What it composes
StatefulSet<app>-mongo— single replica on a Longhorn-encrypted PVC.Service<app>-mongo— ClusterIP only.Secret— root password from a SOPS-encrypted Secret.- PVC annotation —
k8up.io/backup: "true"so the backups component snapshots it.
How an app uses it
# k8s/apps/talos/<app>/kustomization.yaml
components:
- ../../../components/talos/mongodb
The app's Deployment connects to mongodb://<app>-mongo:27017 with credentials pulled from the app's SOPS-encrypted Secret.
Why a StatefulSet and not an operator
CNPG has a first-class Kubernetes operator with Cluster CRDs, replica management, point-in-time recovery, etc. The MongoDB equivalents (Percona, MongoDB Inc.'s own operator) are more invasive for the size of the homelab — they introduce CRDs the homelab doesn't otherwise need.
A plain StatefulSet with one replica is enough for the use case: small per-app document stores, backed up logically by Mongo's mongodump via k8up's backupcommand hook.
Operational notes
- The MongoDB driver in each consuming app usually has reconnect logic — short pod restarts don't propagate as user-visible errors.
- Restoring is via k8up
Restoreagainst the backup snapshot; the restored dump is replayed withmongorestore. The path is more bespoke than the postgres-restore runbook; document the per-app procedure in the app's mdx when relevant. - Considered consolidating to a single shared MongoDB instance — rejected because cross-app authentication and quota management would be more work than running a separate StatefulSet per app.
Cluster Deployment
- Image:
mongo:6.0.28-jammy@sha256:a90cef0143bed76540c2b7e6f299a02165e59b07e459b2fd7fef031c5accf5fd
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- args:
- '--auth'
image: mongo:6.0.28-jammy@sha256:a90cef0143bed76540c2b7e6f299a02165e59b07e459b2fd7fef031c5accf5fd
name: mongodb
ports:
- containerPort: 27012
volumeMounts:
- mountPath: /data/db
name: mongodb-data
volumeClaimTemplates:
- metadata:
name: mongodb-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: longhorn-encrypted