Appearance
First deploy
The end-to-end steps for standing up FlowRunner the first time: set the environment, build and start, let the database indexes create themselves, and confirm the app is healthy.
The steps
1. Set the environment variables
At minimum you need the required variables (AUTH_SECRET, MONGODB_URI, AUTH_URL, AUTH_TRUST_HOST), plus any optional ones for features you want. Full table in Environment variables.
2. Deploy the app
Build and start with Yarn, or push to Vercel and let it run the build:
bash
yarn install
yarn build
yarn startWARNING
Use Yarn, never npm install. npm rewrites the lockfile and can break the build in ways that only surface in CI or production.
3. Indexes self-create
You do not run a migration for a fresh install. The data layer calls ensureIndexesOnce on first database access, which creates every index the app relies on — unique keys, the newest-first lookups, and the TTL index that expires run history. It is idempotent: Mongo no-ops any index that already exists, so it's safe on every boot.
4. Existing data only — backfill tenancy
Skip this on a fresh install.
If you are upgrading an older single-owner install to the multi-tenant model, run migrateTenancy(db) once to backfill workspaces and memberships. It is idempotent and safe to re-run: it gives every user a personal workspace with an owner membership, then assigns any project missing a workspaceId to its author's personal workspace.
text
migrateTenancy(db) → { workspacesCreated, projectsUpdated }The source lives at src/lib/tenancy/migrate.ts. A brand-new install has no legacy projects to backfill, so there is nothing to run.
5. Verify with the health check
Confirm the app is up and reaching MongoDB:
bash
curl -sS https://<your-host>/api/healthA healthy deploy returns 200 with a body like:
json
{
"ok": true,
"checks": {
"db": "ok",
"secretsVault": "configured",
"scheduler": "configured"
}
}The checks object doubles as a configuration audit: secretsVault and scheduler read configured only when SECRETS_KEY and CRON_SECRET are set. If you expected a feature to be on and it reads disabled, the variable didn't reach the runtime. A 503 means the database is unreachable — check MONGODB_URI and network access. See Health & monitoring.
TIP
After the first successful health check, point your uptime monitor at /api/health so you find out about a database outage before your users do.