Storage-substrate batch (W2.5.A) — closes #254 by shipping the three upstream-subchart umbrella Blueprints that the Flux HRs at clusters/_template/bootstrap-kit/{15-external-secrets,16-cnpg,17-valkey} .yaml (merged via PR #262) target. Each chart follows the canonical umbrella pattern documented in docs/BLUEPRINT-AUTHORING.md §11.1: Chart.yaml declares the upstream chart under `dependencies:` so `helm dependency build` bundles the upstream payload into the OCI artifact, and Catalyst-curated overlay values + templates sit alongside in chart/values.yaml + chart/templates/. Per-chart highlights: - bp-external-secrets/1.0.0 — wraps external-secrets/external-secrets 0.10.7. Ships a default `vault-region1` ClusterSecretStore (via Helm post-install/post-upgrade hook to defer the CR application until the upstream chart's CRDs are registered) wired to the in-cluster bp-openbao service. clusterSecretStore.enabled toggle lets cluster overlays opt out and author their own multi-region CRs. - bp-cnpg/1.0.0 — wraps cnpg/cloudnative-pg 0.28.0. Operator-only surface (Cluster CRs are per-Application). CRDs ship in-chart so bp-powerdns / bp-keycloak / bp-gitea / bp-langfuse / bp-grafana / bp-temporal / bp-matrix / bp-llm-gateway / bp-bge / bp-nemo-guardrails / bp-openmeter / pool-domain-manager can `dependsOn: bp-cnpg` via Flux — closing #254 (bp-powerdns CreateContainerConfigError on pdns-pg-app secret). - bp-valkey/1.0.0 — wraps bitnami/valkey 5.5.1. BSD-3 Redis-compatible cache, replication architecture, password auth ON, NetworkPolicy ON, replicas 0 by default for solo Sovereigns (cluster overlays bump for HA). Application-tier cache only — Catalyst control plane uses NATS JetStream KV (per ARCHITECTURE.md §5). Per docs/BLUEPRINT-AUTHORING.md §11.2 (issue #182): every observability toggle defaults `false` (ServiceMonitor / PodMonitor / PrometheusRule / metrics sidecar) and is operator-tunable via per-cluster overlay once bp-kube-prometheus-stack reconciles. Each chart ships tests/observability-toggle.sh covering default-off, opt-in (--api-versions monitoring.coreos.com/v1 to simulate the CRDs), and explicit-off cases. Per docs/INVIOLABLE-PRINCIPLES.md #4 (never hardcode): every upstream version, namespace, server URL, role, and password toggle is exposed under values.yaml. Cluster overlays in clusters/<sovereign>/ may override without rebuilding the Blueprint OCI artifact. helm lint: 1 chart(s) linted, 0 chart(s) failed (each, INFO icon-recommended only) helm template default render kinds: bp-external-secrets: ClusterRole, ClusterRoleBinding, ClusterSecretStore, CustomResourceDefinition, Deployment, Role, RoleBinding, Secret, Service, ServiceAccount, ValidatingWebhookConfiguration bp-cnpg: ClusterRole, ClusterRoleBinding, ConfigMap, CustomResourceDefinition, Deployment, MutatingWebhookConfiguration, Service, ServiceAccount, ValidatingWebhookConfiguration bp-valkey: ConfigMap, NetworkPolicy, PodDisruptionBudget, Secret, Service, ServiceAccount, StatefulSet Closes #254 Co-authored-by: hatiyildiz <hatice.yildiz@openova.io> |
||
|---|---|---|
| .. | ||
| chart | ||
| blueprint.yaml | ||
| README.md | ||
CNPG (CloudNative PostgreSQL)
Production-grade PostgreSQL operator. Application Blueprint (see docs/PLATFORM-TECH-STACK.md §4.1 — Data services). Used by Organizations that want managed Postgres; also the underlying engine for FerretDB (MongoDB-compatible) and Gitea metadata. Replication via WAL streaming to async standby (Application-tier choice).
Status: Accepted | Updated: 2026-04-27
Overview
CloudNative PostgreSQL (CNPG) provides production-grade PostgreSQL with:
- Kubernetes-native operator
- WAL streaming for multi-region DR
- Automated backups to SeaweedFS/S3
- High availability with automatic failover
Architecture
Single Region
flowchart TB
subgraph Cluster["CNPG Cluster"]
Primary[Primary]
Replica1[Replica 1]
Replica2[Replica 2]
end
subgraph Backup["Backup"]
SeaweedFS[SeaweedFS]
end
Primary -->|"WAL Stream"| Replica1
Primary -->|"WAL Stream"| Replica2
Primary -->|"WAL Archive"| SeaweedFS
Multi-Region DR
flowchart TB
subgraph Region1["Region 1 (Primary)"]
PG1[CNPG Primary]
end
subgraph Region2["Region 2 (DR)"]
PG2[CNPG Standby]
end
subgraph Backup["Backup"]
SeaweedFS[SeaweedFS]
end
PG1 -->|"WAL Streaming"| PG2
PG1 -->|"WAL Archive"| SeaweedFS
PG2 -->|"WAL Restore"| SeaweedFS
Configuration
Cluster Definition
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: <org>-postgres
namespace: databases
spec:
instances: 3
postgresql:
parameters:
max_connections: "200"
shared_buffers: 256MB
storage:
size: 10Gi
storageClass: <storage-class>
backup:
barmanObjectStore:
destinationPath: s3://cnpg-backups/<org>
endpointURL: http://seaweedfs.storage.svc:8333
s3Credentials:
accessKeyId:
name: seaweedfs-credentials
key: access-key
secretAccessKey:
name: seaweedfs-credentials
key: secret-key
wal:
compression: gzip
retentionPolicy: "30d"
monitoring:
enablePodMonitor: true
DR Replica (Region 2)
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: <org>-postgres-dr
namespace: databases
spec:
instances: 1
replica:
enabled: true
source: <org>-postgres
externalClusters:
- name: <org>-postgres
connectionParameters:
host: postgres.<env>.<sovereign-domain>
user: streaming_replica
password:
name: pg-replica-credentials
key: password
Backup Strategy
| Type | Schedule | Retention |
|---|---|---|
| WAL Archive | Continuous | 7 days |
| Base Backup | Daily 2 AM | 30 days |
| Point-in-Time | On-demand | Per backup |
Scheduled Backup
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: <org>-daily-backup
namespace: databases
spec:
schedule: "0 2 * * *"
backupOwnerReference: self
cluster:
name: <org>-postgres
Failover
Automatic (Within Region)
CNPG automatically promotes replicas when primary fails.
Manual (Cross-Region)
# Promote DR cluster
kubectl cnpg promote <org>-postgres-dr -n databases
Monitoring
| Metric | Description |
|---|---|
cnpg_pg_replication_lag |
Replication lag in seconds |
cnpg_pg_database_size_bytes |
Database size |
cnpg_pg_stat_activity_count |
Active connections |
PgBouncer Integration
Connection pooling with PgBouncer:
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: <org>-pooler
namespace: databases
spec:
cluster:
name: <org>-postgres
instances: 2
type: rw
pgbouncer:
poolMode: transaction
parameters:
max_client_conn: "1000"
default_pool_size: "20"
Part of OpenOva