Deployment
Run Sereal in production with Docker, and keep the schema in sync.
The supported way to run Sereal is Docker Compose against a Supabase project you
control. Other targets (bare npm start, non-Supabase Postgres, managed PaaS)
are possible but undocumented — see the unsupported-paths list in
INSTALL.md.
Run it
docker compose up -d --buildThe first build runs next build and takes a few minutes; later starts are
fast. The app serves plain HTTP on port 3000. There is no pre-built image
yet — Compose builds from source on first run.
Put it behind TLS
Port 3000 is plain HTTP, which is fine on a trusted private network. Do not expose it directly to the internet — Supabase auth tokens ride in cookies and need TLS. Front it with a reverse proxy (Caddy, nginx) or a Cloudflare Tunnel and terminate HTTPS there.
Keeping the schema in sync
Code expects the database schema to already match. The golden rule: apply migrations before starting new code. Doing it the other way round lets new code write against a schema that isn't there yet, causing quiet degradation.
supabase db push --linked # apply any new migrations
npm run check:migrations # expect: Migration parity OKIf check:migrations reports drift, stop and investigate before serving traffic.
Upgrading
When a new version ships:
git pull origin main
supabase db push --linked # migrations first
docker compose up -d --build # then the new image
npm run check:migrations # confirm parity
curl -sf http://localhost:3000/api/health | jq .okCheck Release notes between versions for anything that changes operator behavior.
Backups
Supabase Cloud handles backups automatically on paid tiers. On the free tier,
set up your own database dump schedule. The maintainer's GCS-based approach is
documented as a reference (not a supported path) in
docs/backup-restore.md.
Scheduled jobs
Deal polling, the email digest, and value-chart snapshots run via /api/cron/*
routes guarded by CRON_SECRET. Point an external scheduler (cron, a cloud
scheduler, a homelab timer) at those endpoints with the secret in the request
header. Without a scheduler the app still runs — you just won't get automated
deal checks or digests.