apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: pg-gitlab namespace: gitlab spec: imageName: ghcr.io/cloudnative-pg/postgresql:16 instances: 3 # 3 instances for production HA # Database resources (homelab-friendly requests, burstable CPU) resources: requests: memory: "1Gi" cpu: "50m" limits: memory: "4Gi" cpu: "500m" # Spread replicas across different nodes affinity: topologyKey: kubernetes.io/hostname storage: size: 50Gi # Increased for production storageClass: rook-ceph-block primaryUpdateStrategy: unsupervised bootstrap: initdb: database: gitlabhq_production owner: app postInitSQL: - CREATE EXTENSION IF NOT EXISTS pg_trgm; - CREATE EXTENSION IF NOT EXISTS btree_gist; # PostgreSQL configuration tuning for GitLab postgresql: parameters: max_connections: "400" shared_buffers: "1GB" effective_cache_size: "3GB" maintenance_work_mem: "256MB" checkpoint_completion_target: "0.9" wal_buffers: "16MB" default_statistics_target: "100" random_page_cost: "1.1" effective_io_concurrency: "200" work_mem: "16MB" min_wal_size: "1GB" max_wal_size: "4GB" max_worker_processes: "4" max_parallel_workers_per_gather: "2" max_parallel_workers: "4" # Backup configuration - repointed to VPS MinIO 2026-08-22 (GitLab # cross-site replication plan, see # /home/scooby/.claude/plans/jiggly-snacking-iverson.md's "GitLab True # Cross-Site Replication" section). Was gitlab-minio-svc (in-cluster, # same Ceph the backup is meant to protect against). Also doubles as # the initial-seed source for the VPS's own pg-gitlab replica # (bootstrap.recovery, Phase 1c) - same barmanObjectStore block serves # both purposes, matching the Authentik precedent # (infrastructure/authentik/manifests/cnpg-cluster.yaml). backup: barmanObjectStore: destinationPath: s3://cnpg-backups/pg-gitlab endpointURL: http://100.108.113.41:9000 s3Credentials: accessKeyId: name: vps-minio-secret key: accesskey secretAccessKey: name: vps-minio-secret key: secretkey wal: compression: gzip maxParallel: 2 retentionPolicy: "30d" monitoring: enablePodMonitor: true # GitLab cross-site replication Phase 1c stage 2 (see # /home/scooby/.claude/plans/jiggly-snacking-iverson.md) - streaming # replication to/from the VPS's pg-gitlab cluster, alongside (not # replacing) the barmanObjectStore backup above. Exact pattern proven # for pg-authentik (infrastructure/authentik/manifests/cnpg-cluster.yaml). # # Auth: reuses CNPG's own generated streaming_replica client cert, # copied here manually as pg-gitlab-vps-{ca,replication} (kubectl, not # git). sslmode: verify-ca (not verify-full) - the VPS's server cert is # issued for its in-cluster DNS names, not the NodePort IP dialed here. # # Reachable via 100.108.113.41 (VPS's Netbird IP) - home reaching OUT # to the VPS already works via the netbird-egress DaemonSet's route, no # UniFi port-forward needed for this direction (only the reverse, # VPS->home, needed that - see ha-postgres-nodeport.yaml). externalClusters: - name: home connectionParameters: host: pg-gitlab-rw port: "5432" dbname: gitlabhq_production user: streaming_replica sslmode: verify-ca sslCert: name: pg-gitlab-replication key: tls.crt sslKey: name: pg-gitlab-replication key: tls.key sslRootCert: name: pg-gitlab-ca key: ca.crt - name: vps connectionParameters: host: 100.108.113.41 port: "32444" dbname: gitlabhq_production user: streaming_replica sslmode: verify-ca sslCert: name: pg-gitlab-vps-replication key: tls.crt sslKey: name: pg-gitlab-vps-replication key: tls.key sslRootCert: name: pg-gitlab-vps-ca key: ca.crt # Distributed topology: both sides agree home is primary today. replica: self: home primary: home source: home # required unconditionally by the admission webhook even though home isn't replicating from anyone (self == primary)