Wire schema v1 into a manual Supabase migration and vendor the real stack
- Move db/schema.sql to supabase/migrations/ as the first supabase CLI migration (manual `db push` only, no automated runner); re-add the gebos_ingest role + grants there since init.sql never re-runs - Add gebos-postgres-passwords oneshot on db-host: syncs role passwords from sops (LoadCredential, journal-safe), makes supabase_admin SUPERUSER and hands the auth schema to supabase_auth_admin to match the upstream supabase/postgres image; add pg_hba rule for 10.0.0.0/8 - Vendor the official docker-compose (studio/kong/auth/rest/meta only, external Postgres, loopback Studio with no Kong dashboard route) plus kong.yml (trimmed) and kong-entrypoint.sh (verbatim); tested: compose config, Kong config parse, migration applied on TimescaleDB pg17 - Document decisions as ADRs 0001-0004 (migrations, passwords, vendored stack, JWT API keys incl. verify/mint procedure) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# Database migrations
|
||||
|
||||
Plain-SQL migrations in `migrations/`, applied **manually** with the supabase
|
||||
CLI (available in the dev shell). There is deliberately no automated runner:
|
||||
schema changes are rare, deliberate, admin-level operations.
|
||||
|
||||
The CLI records what has been applied in
|
||||
`supabase_migrations.schema_migrations` on the target database, so pushing is
|
||||
incremental and re-running it is safe.
|
||||
|
||||
## Applying to prod (db-host)
|
||||
|
||||
Postgres on db-host only accepts connections from the private network, so go
|
||||
through an SSH tunnel:
|
||||
|
||||
```sh
|
||||
# terminal 1 — tunnel to db-host's loopback
|
||||
ssh -L 15432:127.0.0.1:5432 deploy@db.gebos.online
|
||||
|
||||
# terminal 2 — from the repo root, inside `nix develop`
|
||||
PGPASS=$(sops -d --extract '["postgres_admin_password"]' nix/secrets/secrets.yaml)
|
||||
supabase db push --db-url "postgres://postgres:${PGPASS}@127.0.0.1:15432/postgres"
|
||||
```
|
||||
|
||||
The `postgres` superuser password is set from the same sops secret by the
|
||||
`gebos-postgres-passwords` oneshot on db-host (see
|
||||
`nix/modules/gebos-postgres.nix`), so it only works after the first deploy of
|
||||
that unit.
|
||||
|
||||
## Adding a migration
|
||||
|
||||
```sh
|
||||
supabase migration new <short_name> # creates migrations/<timestamp>_<short_name>.sql
|
||||
```
|
||||
|
||||
Write plain SQL. Conventions:
|
||||
|
||||
* Migrations are ordered and applied exactly once — they do NOT need to be
|
||||
idempotent (the schema-v1 file's `CREATE TYPE`s aren't).
|
||||
* Cluster bootstrap (Supabase schemas/roles, extensions that need
|
||||
`shared_preload_libraries`) belongs in `nix/supabase/init.sql`, not here.
|
||||
* Role passwords never go in migrations — they are synced from sops by the
|
||||
`gebos-postgres-passwords` unit.
|
||||
|
||||
## Local dev
|
||||
|
||||
`nix run .#dev` starts a plain Postgres via process-compose; apply migrations
|
||||
to it the same way:
|
||||
|
||||
```sh
|
||||
supabase db push --db-url "postgres://gebos_ingest:dev@127.0.0.1:5432/gebos"
|
||||
```
|
||||
|
||||
(Note: the dev database has no TimescaleDB unless the process-compose postgres
|
||||
gains the extension — `create_hypertable` calls will fail there until then.)
|
||||
Reference in New Issue
Block a user