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
This commit is contained in:
78
docs/database.md
Normal file
78
docs/database.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# 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."
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```yaml
|
||||
# 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`:
|
||||
|
||||
```sql
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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
|
||||
Reference in New Issue
Block a user