Deployment
Take Synapass to staging and production with confidence.
The deploy scripts are idempotent: re-running them is a safe restart-and-verify. That property is what makes day-two operations boring — roll forward, never hand-edit a running host.
Staging vs production#
| Concern | Staging | Production |
|---|---|---|
app.environment | staging | production (fails closed on unsafe config) |
| Migrations | auto_migrate: true | auto_migrate: false + synapass migrate as a release step |
| Admin key | Generated, stored in .env | Generated, stored in a secret manager, injected as env |
| Dashboard origin | http://localhost:3000 | Exact origin; wildcards refused |
| pprof | Off | Off — /debug/pprof is unauthenticated |
Reverse proxy#
Bind the gateway to loopback on a host that sits behind a proxy, and let the proxy own TLS:
http:
addr: 127.0.0.1:8080
trusted_proxies: ["10.0.0.0/8"] # only the proxies in front of you
cors_allowed_origins:
- https://console.example.com # exact origin, never *Only list CIDRs that genuinely terminate in front of the gateway. Honouring
X-Forwarded-For from anywhere lets a client forge its own source address in
logs and rate limits.
Production validation#
In environment: production the gateway refuses to start on unsafe
configuration:
- a CORS wildcard,
- a scoped admin surface with no bootstrap admin key,
- tracing configured with no OTLP endpoint.
This is deliberate: a gateway that silently boots half-secured is worse than one that refuses loudly. Fix the config and restart.
Upgrades#
Docker path — pull and re-verify, data untouched:
./scripts/deploy.sh # updates the checkout, restarts, waits for /readyNative path — build, migrate, restart the units:
make build
synapass migrate # when auto_migrate is false
sudo systemctl restart synapass-gateway synapass-dashboardProduction Linux hosts use the systemd units in deploy/systemd/ (including
synapass-dashboard.service); Windows hosts run native up from Task
Scheduler.
Backups#
The system of record is PostgreSQL; Redis holds limits, budgets, cache, and health state (reconstructible); ClickHouse holds usage and traces.
- Back up PostgreSQL on a schedule — it owns tenants, keys (digests), providers, models, policies, and audit logs.
- Snapshot volumes before major upgrades (
deploy.sh resetdeletes volumes, after a--yesconfirmation — that command is for starting over, not for upgrading). - Keep
.envout of backups-as-code. Secrets live in the environment or a secret manager, never in the repo.
Health checks#
| Probe | Endpoint | Touches dependencies? |
|---|---|---|
| Liveness | GET /health | No — a database blip must not cause an orchestrator to restart every replica |
| Readiness | GET /ready | Yes — what a load balancer asks; checks Postgres, Redis, providers |
Gate load-balancer membership on /ready, restarts on /health.
Observability from minute one#
Every deployment exposes Prometheus metrics (/metrics), OTLP traces, JSON
logs, and Grafana dashboards with alert rules. Wire the alert rules before you
need them — see Observability.