Skip to content

Operations and hosting

The reference deployment uses GitHub Actions, Docker, Caddy, a production MySQL host, and disposable per-PR MySQL databases.

Repository operators should follow the complete hosting guide. It covers DNS, GitHub secrets and environments, VPS bootstrap, deployment, admin access modes, email/payment adapters, migration compatibility, backups, restore drills, and monitoring.

Admin access decision

Admin authentication is an operational environment concern, not a feature-spec concern. The feature specs describe the product contract—email magic links, sessions, account selection, and authorization—while HOSTING.md is the authoritative runbook for deployment secrets, provider wiring, preview databases, and operator access. This guide summarizes that decision without duplicating the secret-bearing setup.

  • Production at /admin/ requires a delivered email magic link. It has DEMO_AUTH_ENABLED=false, so no email-free login button is expected.
  • Same-repository PR previews have isolated MySQL databases, seeded demo data, DEMO_AUTH_ENABLED=true, and mocked email/payment boundaries. Their supported shortcut is Open demo studio.
  • Local development uses the same demo configuration when the command in the repository README is used.
  • /demo/ is the attendee-facing demo and is separate from /admin/.

The reference VPS has two application containers: the production container serves https://booking.title.dk, while a separate booking-demo-<release> container serves the full demo environment at https://demo.booking.title.dk. The demo has its own database and seeded Harbour Yoga data. Production does not route or expose /demo; the attendee demo is available only at https://demo.booking.title.dk/demo/.

The demo hostname exposes the same route families as production: /admin, /api, /api/docs, /api/openapi.json, and /docs; its /demo/ path is the attendee-facing reference consumer. It uses mocked email and payment adapters, while production must use real providers.

The application selects the root index from the request hostname: the demo host shows a demo index linking to /demo/, while the production host shows the marketing placeholder. Production does not expose /demo; that route returns not found there.

The production application can be database-ready while email is still misconfigured. Confirm both public endpoints and the private environment file as described in HOSTING.md.

Release behavior

  • CI must succeed before deployment.
  • Production is backed up before Drizzle migrations.
  • The previous application remains active until the replacement passes database-backed readiness.
  • PRs from the repository receive pr-<number> environments and isolated schemas.
  • Closing a PR removes its route, container, user, credentials, and database.

Schema migrations must follow expand/contract rules. A container switch is non-disruptive, but destructive or locking SQL can still interrupt the old release.

Booking SaaS implementation documentation