Files
wild-directory/supabase/notes.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

127 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Supabase Notes
## Overview
Supabase is a multi-component application. All components run in the `supabase` namespace:
| Component | Image | Role |
|-----------|-------|------|
| `db` | supabase/postgres | PostgreSQL with Supabase extensions |
| `kong` | kong/kong | API gateway, entry point for all traffic |
| `auth` | supabase/gotrue | JWT-based authentication |
| `rest` | postgrest/postgrest | Auto-generated REST API from Postgres |
| `realtime` | supabase/realtime | WebSocket subscriptions |
| `storage` + `imgproxy` | supabase/storage-api + darthsim/imgproxy | File storage (imgproxy as sidecar) |
| `meta` | supabase/postgres-meta | DB introspection for Studio |
| `studio` | supabase/studio | Web dashboard (protected by Kong basic-auth) |
Traffic flows: browser → Traefik → Kong (port 8000) → individual services.
## First-Deploy Checklist
1. Add and deploy with: `wild app add supabase && wild app deploy supabase`
2. Wait for postgres to initialize (~23 min on first boot — it runs SQL init scripts)
3. Access the Studio at `https://supabase.<your-domain>` using the dashboard credentials
4. **Replace example API keys before going to production** (see below)
## JWT Keys — MUST Replace for Production
The default `jwtSecret`, `anonKey`, and `serviceRoleKey` in `secrets.yaml` are Supabase's well-known **example keys** (publicly known, expire Jan 2027). They are sufficient for testing but **must not be used in production**.
Generate new keys using the built-in script:
```bash
wild app run supabase generate-keys
```
Then copy the output values into `secrets.yaml` and redeploy:
```bash
wild app deploy supabase
```
The postgres database stores the JWT secret in its settings (`app.settings.jwt_secret`). After replacing keys, the postgres pod must restart to pick up the new secret — a redeploy handles this.
## Postgres — Internal Database
Supabase uses its own dedicated postgres instance (`supabase/postgres` image) rather than the shared Wild Cloud postgres app. This image includes:
- ~390 extensions pre-compiled (pgjwt, wal2json, vector, pg_net, etc.)
- Supabase service roles (supabase_admin, authenticator, supabase_auth_admin, supabase_storage_admin, etc.)
- Initialization scripts for realtime, webhooks, JWT settings
All Supabase service roles (auth, storage, realtime, etc.) use the same password as the postgres admin (`dbPassword` secret). This is the Supabase default behavior.
### Bootstrap User: supabase_admin
`POSTGRES_USER` is set to `supabase_admin` (not `postgres`). This is required because the image's `migrate.sh` script connects immediately as `supabase_admin` before running any init scripts. Using `POSTGRES_USER=postgres` would make postgres the bootstrap superuser, which prevents `migrate.sh` from demoting it (PostgreSQL prohibits removing SUPERUSER from the bootstrap user).
With `POSTGRES_USER=supabase_admin`:
1. `initdb` creates `supabase_admin` as the bootstrap superuser
2. `migrate.sh` connects as `supabase_admin` and creates the `postgres` role
3. After init-scripts run, `migrate.sh` demotes `postgres` to non-superuser (this is Supabase's intended model)
The `postgres` user remains available with database-level privileges. All Supabase service roles use specific functional accounts (supabase_auth_admin, authenticator, etc.), not the postgres superuser.
### Volume Mount: /var/lib/postgresql (parent dir)
The PVC is mounted at `/var/lib/postgresql` (the parent), NOT at `/var/lib/postgresql/data` (PGDATA). This is required because Longhorn's ext4 filesystem creates a `lost+found` directory, which blocks postgres `initdb` when the PVC is mounted directly at PGDATA. With the parent-dir mount, `initdb` creates `/var/lib/postgresql/data` as a subdirectory, leaving `lost+found` at the parent level where it doesn't interfere.
## Realtime Tenant ID
The Realtime service must identify itself with the tenant ID `realtime-dev`. The Deployment sets `spec.template.spec.hostname: realtime-dev` so the Elixir application seeds itself with this tenant ID. The Kubernetes service for Realtime is also named `realtime-dev` so Kong can route to it correctly.
## Storage
File storage uses the local filesystem backend by default. Objects are stored in the `supabase-storage` PVC. The `imgproxy` container is a sidecar in the same pod, sharing the storage PVC for image transformation.
For S3-backed storage: edit `deployment-storage.yaml` to change `STORAGE_BACKEND` to `s3` and add S3 credentials as secrets.
## SMTP
SMTP is required for auth email flows (email confirmation, password reset). Configure the `smtp` app dependency and it will be wired automatically. If you want to disable email confirmation during initial testing, you can temporarily set `GOTRUE_MAILER_AUTOCONFIRM=true` in `deployment-auth.yaml`.
## Studio Dashboard Credentials
The Studio dashboard is protected by HTTP Basic Auth via Kong. Credentials:
- Username: configured via `dashboardUsername` config key (default: `supabase`)
- Password: auto-generated `dashboardPassword` secret
To view the generated password:
```bash
kubectl -n supabase get secret supabase-secrets -o jsonpath='{.data.dashboardPassword}' | base64 -d
```
## Connecting Applications
Applications connect to Supabase via the Kong API gateway:
- **REST API**: `https://supabase.<domain>/rest/v1/`
- **Auth**: `https://supabase.<domain>/auth/v1/`
- **Realtime**: `wss://supabase.<domain>/realtime/v1/`
- **Storage**: `https://supabase.<domain>/storage/v1/`
Use the `anonKey` for client-side (browser) access and `serviceRoleKey` for server-side (admin) access.
## Supabase JavaScript Client
```js
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
'https://supabase.<your-domain>',
'<anonKey>' // from secrets.yaml
)
```
## Troubleshooting
**Postgres won't start**: Check that the supabase/postgres image can be pulled and that the PVC is bound.
**Auth returns 500**: Postgres is not ready or the init scripts haven't completed. Check DB pod logs and wait for all init SQL to finish.
**Kong returns 401 for all requests**: The `anonKey` in secrets doesn't match the `jwtSecret`. Regenerate keys with `wild app run supabase generate-keys`.
**Realtime health check fails**: The pod hostname may not be `realtime-dev`. Check the Deployment `spec.template.spec.hostname` field.
**Studio shows "Project not found"**: Studio needs Kong to be healthy. Check Kong pod logs for declarative config errors.