feat(deploy): inline bootstrap into db-init — compose is the single source; DB_PORT everywhere

z_rls_role.sh is gone. The db-init service carries the bootstrap SQL
inline (the script's docker-exec/local-socket mode was its only reason
to exist as a file, and the no-clone deployment path could not use it:
docker bind-mounts of missing host paths auto-create empty DIRECTORIES,
so a compose-only install got '/z_rls_role.sh: no such file').

The inline form surfaced two silent bugs the script had masked:
- psql defaulted its DATABASE to the username (POSTGRES_DB is not a
  libpq variable) — the ownership loop ran against 'postgres' and
  no-opped on existing volumes. Fixed with PGDATABASE: bookhoard.
- PGPORT was never propagated: with a custom DB_PORT, db-init dialed
  5432 while Postgres listened on the custom port. Fixed with
  PGPORT: ${DB_PORT:-5432} — DB_PORT is now a variable in every
  connection path (db listener, host mappings, app, db-init).

Also removed the db service's initdb.d mount: the app executes the full
schema as the runtime-role owner on every boot incl. first (pg_trgm is
a trusted extension; the db owner can create it), so the bootstrap SQL
was its only content.

Verified: dev two-boot against the existing 40-table volume (owners
converged, 0 off-owner tables/functions), custom-port throwaway
(DB_PORT=15432: db-init + app both on the custom port, healthy),
default-port throwaway (fresh volume, healthy), full Go suite green.
Manual repair path: docker compose run --rm db-init.
This commit is contained in:
John O'Keefe committed 2026-10-29 13:06:16 -04:00
1 parent cf73eec2e4
commit 304ea9599f
4 files changed
+73 -90

No files matched your search

+2 -2
View File
@@ -108,8 +108,8 @@ inside quoted attribute values (gotcha #1 below), so dynamic
Per-user library visibility (`library_visibility` table, default-ALLOW:
every user sees every library unless an admin hides one) is enforced by
**Postgres RLS** — one source of truth: the labeled policy block in
`database/schema/schema.sql` + the runtime role
(`database/schema/z_rls_role.sh`).
`database/schema/schema.sql` + the runtime role provisioned by the
`db-init` compose service.
- **The engine is the enforcement.** Every `media_items` read is
filtered by the policy, which joins `library_visibility` on the