Skip to content

Self-hosting

Quayside is designed to be self-hosted in your own cloud or on-prem environment. This page covers the shape of a production deployment.

What runs where

  • Postgres — managed service is fine (AWS RDS, Azure Database for PostgreSQL, Cloud SQL). Quayside uses one database for the runtime; you point it at the connection string via QUAYSIDE_DATABASE_URL.
  • API service — Python 3.12+, run with uvicorn behind a reverse proxy (nginx, ALB, ingress). The service is stateless (state lives in Postgres) — scale horizontally.
  • Dashboard — Next.js. Build with npm run build and serve with npm start behind the same reverse proxy. Or run as a static export and serve via CDN.
  • CLI — distributed to developer laptops via pipx install quayside-cli (or wherever you publish the wheel).

Run modes

For most production deployments, you’ll want at least:

ConcernWhat you need
TLS terminationReverse proxy or load balancer in front of both API and dashboard
Same-origin vs CORSEasiest: serve API and dashboard on the same origin (/api/v1/* to the API, everything else to the dashboard)
Network egress to LLM providersOnly the API service needs outbound to api.anthropic.com etc.

Required environment variables

The complete list is in Reference → Configuration. The minimum for production:

Terminal window
QUAYSIDE_DATABASE_URL=postgres://...
QUAYSIDE_DEV_MODE=false
QUAYSIDE_JWT_SECRET=<32+ random bytes>
QUAYSIDE_ANTHROPIC_API_KEY=sk-ant-...

Schema management

Terminal window
# First time
quayside-migrate --database-url $QUAYSIDE_DATABASE_URL
# Upgrades — re-run after pulling a new release
quayside-migrate --database-url $QUAYSIDE_DATABASE_URL
# Don't seed in production
# (the dev seed exists only for development)

quayside-migrate tracks applied migrations in _quayside_migrations. It’s idempotent and safe to re-run.

High availability

The Python service is stateless. Run multiple replicas behind a load balancer; sticky sessions are not required. The proxy’s per-request state lives in Postgres and is consistent across replicas.

For Postgres HA, follow your cloud provider’s standard primary + standby setup. The schema doesn’t use any features that require special replication configuration.

Provider API keys

In v1, provider keys (Anthropic, etc.) are shared across all classes in the deployment — one key per provider per process.

Per-class virtual keys (the LiteLLM pattern) are roadmap. When they land, each class can have its own provider identity for clean cost attribution.

For now: rotate provider keys by updating the environment variable and rolling the deployment.

Observability

What to wire up:

  • Process metrics — uvicorn worker count, request rates, response times. Standard FastAPI metrics middleware works.
  • Postgres metrics — connection pool size, query latency. Use your managed-DB monitoring.
  • Audit data — runs and steps tables are designed for SQL roll-ups. Build dashboards on the queries shown in Concepts → Audit.
  • Application logs — uvicorn logs to stdout. Ship to your log aggregator. Quayside’s own logging via logging is light: errors surface, but per-request log lines do not — those live in the audit tables.

Backup

Standard Postgres backup. The audit log is the single most important thing to preserve — that’s the compliance evidence.

Upgrading

Quayside follows additive schema changes (no destructive migrations). Upgrade path:

  1. Pull the new release
  2. quayside-migrate (idempotent — only applies new migrations)
  3. Roll the deployment

If a release ever requires a destructive migration, it’ll be in the changelog.