Deploy Dawn
Dawn deploys as four Vercel projects backed by one PostgreSQL database. The
workspace project packages the Eve runtime from apps/agents as an internal
service; do not create a separate agent project.
Production access: This repository verifies Dawn access tokens but does not provide the identity or session boundary that issues them. Production disables static demo access. Connect an identity boundary that mints short-lived member and patient tokens before exposing the workspace or patient applications. Without a valid token, protected API requests return
401.
Requirements
- A Vercel project for each web application
- A PostgreSQL database that supports the
vector,pg_trgm, andbtree_gistextensions - Production domains for the API, workspace, patient application, and docs
- Node.js 24 and pnpm 11 for release checks and database migrations
Deployment topology
| Project | Root directory | Purpose |
|---|---|---|
| API | apps/api | HTTP API, event cron, and Workflow runtime |
| Workspace | apps/dawn | Staff application with embedded Eve service |
| Patient | apps/patient | Patient application |
| Docs | apps/docs | Technical documentation |
Import the repository once for each project and select the corresponding root
directory. Keep Vercel’s detected Next.js build, install, and output settings.
Verify that Include source files outside of the Root Directory in the Build
Step is enabled because every application imports workspace packages from
packages/.
See Vercel’s monorepo guide for the project setup.
1. Provision PostgreSQL
Create an empty database and keep two connection strings:
| Variable | Use |
|---|---|
DATABASE_URL | Pooled connection used by the API runtime |
DATABASE_URL_DIRECT | Direct connection used by the Drizzle migration runner |
Set both variables in a secure release environment, then run migrations from the repository root:
pnpm install --frozen-lockfile
pnpm db:migrateThe migration runner prefers DATABASE_URL_DIRECT and falls back to
DATABASE_URL. Migrations create the required PostgreSQL extensions. Apply
migrations before deploying code that depends on the new schema.
Do not run pnpm db:seed against production. It creates the fixed local demo
workspace and example patient records.
2. Configure the projects
Set variables separately for Production and Preview. Vercel applies environment
changes only to new deployments, and NEXT_PUBLIC_* values are included in the
browser build, so redeploy after changing them.
API
| Variable | Value |
|---|---|
DATABASE_URL | Pooled production PostgreSQL URL |
CORS_ORIGINS | Exact workspace and patient origins, separated by commas |
DAWN_AUTH_SECRET | Secret of at least 32 characters used to verify access tokens |
CRON_SECRET | Secret of at least 16 characters used to protect event dispatch |
DAWN_SEARCH_EMBEDDING_MODEL | Optional approved 1536-dimensional embedding model |
For example:
CORS_ORIGINS=https://dawn.example.com,https://patient.example.comOrigins must include the scheme and hostname without a path. Dawn matches them exactly and does not allow a wildcard. Preview workspace and patient deployments therefore need their own allowed Preview origins.
Keep DAWN_AUTH_SECRET identical in the API and the trusted identity boundary
that signs Dawn access tokens. Never expose it through a NEXT_PUBLIC_*
variable.
The checked-in apps/api/vercel.json invokes /v1/system/events every minute.
When CRON_SECRET is present, Vercel sends it to the route as a bearer token.
Workspace
| Variable | Value |
|---|---|
NEXT_PUBLIC_API_URL | Public API origin |
NEXT_PUBLIC_DOCS_URL | Public docs origin |
DAWN_API_URL | API origin used server-side by the embedded Eve service |
DAWN_AGENT_ACCESS_TOKEN | Short-lived member token used by Dawn’s API tools |
LANTERN_APP_SECRET | Stable secret of at least 32 characters for Lantern sessions |
LANTERN_RELAY_URL | Reviewed Lantern relay origin |
The embedded Eve service receives the workspace project’s server-side
environment. DAWN_AGENT_ACCESS_TOKEN is required for its Dawn API calls in
production and must be replaced when it expires. Browser model access uses
Lantern; AI_GATEWAY_API_KEY is optional and only needed for non-browser
fallback clients.
Patient
| Variable | Value |
|---|---|
NEXT_PUBLIC_API_URL | Public API origin |
The identity boundary must set a valid patient-scoped dawn_access cookie for
the API origin or otherwise provide the token as a bearer credential.
Docs
The docs project has no required runtime variables.
3. Verify the release
Run the repository checks before promotion:
pnpm check
pnpm lint
pnpm test
pnpm i18n:check
pnpm openapi:check
pnpm format:check
pnpm buildDeploy the API after the migrations complete, then deploy the workspace, patient application, and docs. A push to the configured production branch creates Production deployments for all four connected projects.
Check the public API endpoints:
curl --fail https://api.example.com/health
curl --fail https://api.example.com/capabilities.json
curl --fail https://api.example.com/openapi.json/health confirms that the API function starts; it does not query PostgreSQL.
Use a short-lived access token to verify an authenticated database read:
curl --fail \
-H "Authorization: Bearer $DAWN_ACCESS_TOKEN" \
https://api.example.com/v1/patientsVerify the event dispatcher with the API project’s CRON_SECRET:
curl --fail \
-H "Authorization: Bearer $CRON_SECRET" \
https://api.example.com/v1/system/eventsFinally:
- Open the workspace, patient application, and docs production domains.
- Confirm the API response includes
Access-Control-Allow-Originfor both browser application origins. - Confirm the API project lists the
/v1/system/eventscron in Vercel. - After a controlled mutation, confirm the event appears in the Workflow runs.
Rollback
Promoting a previous Vercel deployment rolls back application code and configuration, but it does not roll back PostgreSQL. Keep schema changes compatible with the previous application release until the new deployment is verified. Repair database changes with a new forward migration.
Troubleshooting
| Symptom | Check |
|---|---|
A build cannot resolve an @dawn/* package | Root directory and inclusion of source files outside it |
| API startup fails during environment parsing | Database URL and minimum secret lengths |
| Browser requests fail CORS checks | Exact scheme and hostname in CORS_ORIGINS |
Protected API requests return 401 | Token expiry, cookie origin, and the shared DAWN_AUTH_SECRET |
| Database routes report missing relations | Production migrations completed against the intended database |
| Event outbox rows remain pending | API cron, CRON_SECRET, and Vercel Workflow runs |
| Dawn cannot send a message | Lantern session, stable LANTERN_APP_SECRET, and reviewed relay URL |