Deployment & Operations
How it ships, how it runs, and how you'd know if it stopped working.
How it's packaged
A multi-stage Docker build compiles three binaries from the same Go module: the service itself, a migration runner, and a small utility that provisions the non-owner database role RLS depends on. The production entrypoint runs migrations to completion, then execs the service — there's no separate migration step to remember.
What actually runs
Pull the image
Multi-stage build, small final image.
Run migrations
Forward-only, applied to completion before anything else starts.
Provision the app role
The non-owner Postgres role that RLS enforces isolation against.
Exec the service
One binary, one process.
Health checks pass, traffic flows
See below for what those checks actually verify.
One web service plus a managed Postgres with pgvector — deliberately not a Kubernetes cluster or a queue-backed mesh of microservices. Fewer moving parts means fewer 3am pages.
Health checks & metrics
| Endpoint | Verifies |
|---|---|
GET /livez | The process is running |
GET /readyz | The database is reachable and migrations are applied |
GET /version | Which build is currently running |
GET /metrics | Prometheus-format metrics |
Warning
Prometheus metrics and the audit trail are live today. OpenTelemetry trace export is designed for, not yet shipped — see Roadmap.
CI
Builds compile the binaries, run unit and integration tests against a real Postgres/pgvector service — never a mock — lint the codebase, validate migrations up, down, and back up, and run a vulnerability scan. On every change, not just release branches.
Backup & restore
Postgres is the single system of record, so your managed-Postgres provider's point-in-time recovery is the primary safety net. If you need to roll back a schema change, use the migration tool's down migrations rather than editing the database by hand.
Related