Files
wild-directory/docs/database.md
Paul Payne 4d983819c9 feat(supabase): add services and statefulset for database management
feat(synapse): update ingress to use traefik ingress class and bump version

feat(syncthing-discovery): introduce syncthing discovery service with deployment and ingress

feat(syncthing-relay): add syncthing relay server with deployment and ingress configuration

fix(taiga): update liveness and readiness probes to use tcpSocket for health checks

fix(taiga): change PVC access mode to ReadWriteMany for media and static storage

feat(traefik): add icon and ignore rules for traefik service

docs(ushahidi): add notes for Redis configuration and Laravel startup probe adjustments

feat(ushahidi): implement dedicated Redis deployment for Ushahidi

fix(vllm): update deployment strategy and readiness/liveness probes for improved stability

fix(writefreely): pin writefreely image version to v0.15.1 for consistency

docs(zulip): add notes for TLS-terminating reverse proxy configuration and expected behavior
2026-07-02 21:34:27 +00:00

2.4 KiB

Database Patterns

PostgreSQL

Always use ?sslmode=disable [WC-SSL]

Wild Cloud's internal PostgreSQL has no SSL configured. Without ?sslmode=disable, connections fail with "The server does not support SSL connections."

defaultSecrets:
  - key: dbUrl
    default: "postgresql://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host }}:{{ .app.db.port }}/{{ .app.db.name }}?sslmode=disable"

Also set PGSSLMODE=disable for apps that use libpq directly.

db-init-job

Include a db-init-job.yaml for every app that uses PostgreSQL. See immich, gitea, or openproject for reference implementations. The job must:

  • Create the database if it doesn't exist
  • Create/update the user with correct credentials
  • Grant permissions
  • Install required extensions (vector, pg_trgm, etc.)
  • Use restartPolicy: OnFailure and runAsUser: 999
  • Be idempotent — safe to re-run after redeploy

Database URL secrets

When an app needs a connection URL with embedded credentials, use a dbUrl secret — do not construct URLs inline:

# Wrong: Kustomize cannot do runtime env var substitution
- name: DB_URL
  value: "postgresql://user:$(DB_PASSWORD)@host/db"

# Correct: use a secret with the full URL
- name: DB_URL
  valueFrom:
    secretKeyRef:
      name: myapp-secrets
      key: dbUrl

MySQL

db-init user password idempotency [WC-DBIN]

CREATE USER IF NOT EXISTS only sets the password on first creation. On redeploy against an existing database the password stays stale, causing "Access denied".

Always follow CREATE USER with ALTER USER:

CREATE USER IF NOT EXISTS '${DB_USERNAME}'@'%' IDENTIFIED BY '${DB_PASSWORD}';
ALTER USER '${DB_USERNAME}'@'%' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON ${DB_DATABASE_NAME}.* TO '${DB_USERNAME}'@'%';
FLUSH PRIVILEGES;

ALTER USER is a no-op when the user was just created — it is safe to always include it.

Required secrets reference

MySQL secrets are copied into <app>-secrets, not mysql-secrets. Reference them as:

secretKeyRef:
  name: myapp-secrets
  key: mysql.rootPassword  # not mysql-secrets / rootPassword

Database env var naming

Name database-related env vars so the backup system can identify them:

  • Database name: include DATABASE, DB_NAME, DBNAME, or __DATABASE
  • Database URLs: value must contain ://
  • Usernames: include USER — these are not patched on restore