Files
railiance-platform/docs/apps-pg.md
tegwick 1a5b65a338 RAILIANCE-WP-0003 T02-T06: provision shared apps-pg cnpg cluster
Adds the shared CloudNativePG cluster apps-pg for S5 application
databases:
- helm/apps-pg-cluster.yaml — Cluster CR, PG 16, 1 instance, 10Gi
- helm/apps-pg-networkpolicies.yaml — egress-to-kube-api +
  ingress-from-cnpg-operator + label-based ingress opt-in
  (railiance.io/postgres-client=apps-pg)
- helm/apps-pg-secret.sops.yaml.template — bootstrap credential
  template (encrypt with SOPS before committing the real .sops.yaml)
- Makefile targets: apps-pg-deploy, apps-pg-status (with cnpg-plugin
  fallback), apps-pg-shell (apps_admin/apps_meta), apps-pg-logs
- docs/apps-pg.md (codex) — consumer onboarding contract clarifying
  the CNPG 1.28 role/database lifecycle boundary

Also fixes helm/gitea-db-cluster.yaml: spec.postgresql.version is not
a valid CNPG v1 field (strict decoding rejects it). Replaced with
spec.imageName matching the live cluster (postgresql:18.1-system-trixie)
so make db-deploy is a no-op instead of an apply rejection.

Live state at commit time: Cluster apps-pg in healthy state, primary
apps-pg-1 Running, smoke-tested via psql from a labeled temp ns.

Co-Authored-By: codex <noreply@openai.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 04:50:40 +02:00

3.5 KiB

apps-pg Shared PostgreSQL Cluster

apps-pg is the shared CloudNativePG cluster for S5 application databases. It lives in the databases namespace and is owned by railiance-platform as an S3 platform service.

Cluster Identity

  • CNPG Cluster: apps-pg
  • Namespace: databases
  • PostgreSQL major version: 16
  • Primary endpoint: apps-pg-rw.databases.svc.cluster.local:5432
  • Read-only endpoint: apps-pg-ro.databases.svc.cluster.local:5432
  • Bootstrap database: apps_meta
  • Bootstrap role: apps_admin

apps_admin is a platform bootstrap and smoke-test role. Do not copy it into application namespaces, use it in S5 runtime configuration, or treat it as a consumer credential.

Consumer Onboarding

Each S5 application gets its own role, database, and runtime Secret. The current flow is platform-administered until OpenBao or a dedicated database onboarding automation owns the lifecycle end to end.

  1. Request an app database in the consuming repo workplan. Include the app name, namespace, database name, role name, intended owners, and any required extensions.

  2. Platform reviews and approves the database/role names. Names should be app-scoped, for example vergabe and vergabe_db.

  3. Platform provisions the backing PostgreSQL role and credential for the approved app. Until automation exists, this is a controlled operator SQL action against apps-pg, not a self-service repo apply.

  4. Add a CNPG Database manifest in the platform-managed database manifests, with spec.cluster.name: apps-pg and spec.owner set to the approved role.

  5. Label the consuming namespace so NetworkPolicy allows access:

    kubectl label namespace <app-namespace> \
      railiance.io/postgres-client=apps-pg
    
  6. Publish or mirror the runtime Secret into the consumer namespace. The Secret should contain only that app's role credential and DSN fields.

  7. Wire the DSN into the application Helm values or runtime configuration. Prefer the RW service for migrations and writes: postgresql://<role>:<password>@apps-pg-rw.databases.svc.cluster.local:5432/<database>.

Example CNPG Database resource:

apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
  name: vergabe-db
  namespace: databases
spec:
  cluster:
    name: apps-pg
  name: vergabe_db
  owner: vergabe

CNPG Boundary

CNPG 1.28 provides a standalone Database CRD. It does not provide a standalone Role CRD in this cluster. Role lifecycle is cluster-scoped, through Cluster.spec.managed.roles or a controlled SQL workflow.

Consumer repos must therefore not assume they can create PostgreSQL roles themselves. They can request a database and consume a runtime Secret after the platform role has been provisioned.

Network Policy

The databases namespace has a default-deny posture. apps-pg accepts client traffic on TCP/5432 only from namespaces labeled:

railiance.io/postgres-client=apps-pg

The CNPG operator in cnpg-system is allowed to manage the cluster on the standard PostgreSQL, instance manager, and metrics ports.

Backup And Roadmap

apps-pg starts as a conservative single-instance, 10Gi cluster to match the current node capacity and existing CNPG footprint. Adding a replica, PgBouncer/CNPG Pooler, resize policy, and CNPG-native backup coverage are follow-up platform work items.

Until backup coverage is explicitly added, consumer onboarding should record whether app data is disposable, externally reproducible, or requires an immediate backup follow-up before production use.