feat(stalwart): deploy stalwart-postgres StatefulSet + backup (DEV-469) #3

Merged
forgejoadmin merged 1 commit from feat/DEV-469-stalwart-postgres into main 2026-08-15 12:06:08 +00:00
Owner

Phase 2 of DEV-467DEV-469.

Purely additive; does not touch stalwart-0, its ConfigMap, PVC, or bootstrap.

Files

  • apps/stalwart/stalwart-postgres.yaml — single-replica StatefulSet (postgres:16-alpine), ClusterIP Service, 10Gi hcloud-volumes-encrypted PVC (subPath pgdata), nodeAffinity csi.hetzner.cloud/location=fsn1. Resources match forgejo-postgres.
  • apps/stalwart/stalwart-postgres-credentials-sealed.yaml — sealed secret with POSTGRES_USER=stalwart, POSTGRES_DB=stalwart, POSTGRES_PASSWORD=<generated>, plus a copy under stalwart-db-password for the future [store.postgres] Stalwart config.
  • apps/stalwart/stalwart-postgres-backup.yaml — daily 02:30 UTC CronJob: pg_dump | gzip | restic backup --stdin into the existing stalwart-s3-backup restic repo, tag stalwart-postgres, independent retention (14d/8w/6m). activeDeadlineSeconds: 1800 mirrors the DEV-464 fix.

Verification (post-merge)

  • ArgoCD sync green.
  • kubectl -n stalwart get pods -l app=stalwart-postgres shows Ready 1/1.
  • psql -h stalwart-postgres.stalwart.svc -U stalwart -d stalwart -c \l from a debug pod succeeds.
  • One backup CronJob run has completed and restic snapshots --tag stalwart-postgres shows the snapshot.
  • stalwart-0 pod age unchanged.

Out of scope

  • No edits to stalwart-config, stalwart-bootstrap-config, or the Stalwart StatefulSet.
  • Stalwart-side [store.postgres] config lands in Phase 4 (cutover).
Phase 2 of [DEV-467](/DEV/issues/DEV-467) — [DEV-469](/DEV/issues/DEV-469). Purely additive; does not touch `stalwart-0`, its ConfigMap, PVC, or bootstrap. ## Files - `apps/stalwart/stalwart-postgres.yaml` — single-replica StatefulSet (postgres:16-alpine), ClusterIP Service, 10Gi hcloud-volumes-encrypted PVC (subPath pgdata), nodeAffinity `csi.hetzner.cloud/location=fsn1`. Resources match `forgejo-postgres`. - `apps/stalwart/stalwart-postgres-credentials-sealed.yaml` — sealed secret with `POSTGRES_USER=stalwart`, `POSTGRES_DB=stalwart`, `POSTGRES_PASSWORD=<generated>`, plus a copy under `stalwart-db-password` for the future `[store.postgres]` Stalwart config. - `apps/stalwart/stalwart-postgres-backup.yaml` — daily 02:30 UTC CronJob: `pg_dump | gzip | restic backup --stdin` into the existing `stalwart-s3-backup` restic repo, tag `stalwart-postgres`, independent retention (14d/8w/6m). `activeDeadlineSeconds: 1800` mirrors the DEV-464 fix. ## Verification (post-merge) - ArgoCD sync green. - `kubectl -n stalwart get pods -l app=stalwart-postgres` shows Ready 1/1. - `psql -h stalwart-postgres.stalwart.svc -U stalwart -d stalwart -c \l` from a debug pod succeeds. - One backup CronJob run has completed and `restic snapshots --tag stalwart-postgres` shows the snapshot. - `stalwart-0` pod age unchanged. ## Out of scope - No edits to `stalwart-config`, `stalwart-bootstrap-config`, or the Stalwart StatefulSet. - Stalwart-side `[store.postgres]` config lands in Phase 4 (cutover).
forgejoadmin added 1 commit 2026-08-15 12:05:52 +00:00
Phase 2 of the Stalwart RocksDB -> PostgreSQL migration (DEV-467).
Purely additive - does not touch the running stalwart-0 pod, its
ConfigMap, PVC, or bootstrap-config.

- stalwart-postgres.yaml: single-replica StatefulSet with a 10Gi
  hcloud-volumes-encrypted PVC (subPath pgdata), ClusterIP Service
  on 5432, nodeAffinity csi.hetzner.cloud/location=fsn1 so the DB
  co-locates with stalwart-0 (which is fsn1-pinned by its PVC).
  Resources match forgejo-postgres (250m/512Mi req, 500m/1Gi lim).
- stalwart-postgres-credentials-sealed.yaml: sealed secret with
  POSTGRES_USER=stalwart, POSTGRES_DB=stalwart, POSTGRES_PASSWORD,
  plus a copy of the password under stalwart-db-password for
  Stalwart's [store.postgres] config in the Phase 4 cutover.
- stalwart-postgres-backup.yaml: daily CronJob at 02:30 UTC that
  streams pg_dump | gzip into the existing stalwart-s3-backup restic
  repo tagged stalwart-postgres, with independent retention keys
  (14d/8w/6m) so it doesn't collide with the RocksDB snapshots.
  activeDeadlineSeconds=1800 mirrors the DEV-464 sibling fix.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
forgejoadmin merged commit 471b6a6109 into main 2026-08-15 12:06:08 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: basicstack/stack.basicstack.de#3
No description provided.