Skip to content

Production - deployment

Production setup for the OpenQuok web, backend, optional CLI auth server, and optional orchestrator workers.

6 min read

Connect your agent today

Draft from chat, review in your calendar, and publish only what you approve.

Start for $0

The production version (openquok.com) is set up for:

1) Vercel for the backend (Express.js) (/backend)

2) Vercel for web (SvelteKit) (/web)

3) (Optional) the CLI auth server (/agent/server — OAuth device flow) Supabase remains the database and auth provider for the API.

It is noted that Orchestrator workers (BullMQ) are not run on Vercel. We deploy separate always-on processes (for example on Railway) that share the same Redis and Supabase credentials as the API. See Configuration - Worker and Orchestrator workflows.

What you need

  • Supabase project (URL, anon key, service role key)
  • Vercel projects for backend/, web/, and optionally agent/server/ (CLI device-flow auth helper — see Configuration - Agent)
  • Recommended: managed Redis for production OAuth flows, BullMQ orchestration, and shared rate-limit counters when RATE_LIMIT_REDIS_ENABLED is on (production default).

Secrets and configuration

  • Never commit real secrets. Use backend/.env.development.example and backend/.env.production.local locally. Use the Vercel dashboard in production.
  • Mirror the same variable names as in backend/config/GlobalConfig.ts (via getEnv / getEnvBoolean / getEnvNumber).
  • Public site origin: set the same canonical HTTPS origin on the backend as FRONTEND_DOMAIN_URL and on the web build as VITE_FRONTEND_DOMAIN_URL (no trailing slash after the host, for example https://www.openquok.com).
  • CORS: include apex and www in ALLOWED_FRONTEND_ORIGINS when both hostnames serve traffic, even though OAuth uses a single canonical origin above.
  • Local HTTPS dev differs: the web app can use an empty VITE_API_BASE_URL and same-origin /api through the dev server. See Vite (SvelteKit).
  • Media publishing (Threads, etc.): for posts with media stored as object keys, set STORAGE_R2_PUBLIC_BASE_URL so workers can build public HTTPS URLs for Meta to fetch. See R2 or local storage.
  • Rate limiting (backend API only): set NOT_SECURED to false on the Vercel backend so production defaults apply.
  • Maintenance cutover: for Supabase region migration or other ops windows, set MAINTENANCE_MODE on the backend, web (server env), and workers together. See Maintenance mode and Supabase backup.

Supabase production migrations

Run schema changes when a release adds tables or RLS under backend/supabase/db/. Re-aggregate locally first:

pnpm backend:db:aggregate-migrations-all

From backend/ (linked to your production project):

cd backend
pnpm db:production:migration-list

There are two ways to apply migrations. One is CLI push — runs the aggregated file under backend/supabase/migrations/:

pnpm db:production:push-db:dry-run
pnpm db:production:push-db

Another one is copy & paste SQL from the module folder (e.g. backend/supabase/db/acquisition/) into the Supabase Dashboard → SQL Editor.

After the SQL succeeds, mark the matching aggregated migration as applied so migration list stays in sync with the remote (use the date segment from the filename, e.g. 20260919 from 20260919_core_structure.sql):

npx supabase@latest migration repair --linked --status applied 20260919
pnpm db:production:migration-list

After a region restore, prefer pnpm prod-backup:relink from the repo root. It links to the target project and repairs the current aggregate date only when remote history is behind. Do not run db push during cutover — restore already applied the schema.

Optional — refresh backend table types from the linked project:

pnpm db:production:typegen

See also Database & migrations for local workflow, aggregation, and pg_cron notes.

Deploy with Vercel

Use the detailed CLI and project settings on Vercel. From the repository root:

pnpm vercel:env:sync:web:prod
pnpm vercel:env:sync:backend:prod
pnpm vercel:env:sync:agent-server:prod
pnpm vercel:deploy:backend:prod
pnpm vercel:deploy:web:prod
pnpm vercel:deploy:agent-server:prod

After deploy, configure OAuth redirect URIs, webhooks, and any third-party dashboards to use your production API URL.

Check API startup logs for rate limiters using store: redis when RATE_LIMIT_REDIS_ENABLED is enabled. If public pages return 503 (SSR maps API 429), see the runbook in Rate limiting.

Deploy orchestrator workers (Railway)

Workers are required when you configure BullMQ transports . Use Configuration → Worker → Railway (workers) for the full CLI flow and service management details.

From the repository root, set up / deploy one persistent service per worker:

# One-time: create services + set production env vars
pnpm railway:setup:integration-refresh
pnpm railway:setup:notification-email
pnpm railway:setup:scheduled-social-post
# Update env (safe to re-run)
pnpm railway:env:sync:integration-refresh:prod
pnpm railway:env:sync:notification-email:prod
pnpm railway:env:sync:scheduled-social-post:prod
# Deploy each worker (Railway CLI must be linked to the target service)
pnpm railway:deploy:integration-refresh
pnpm railway:deploy:notification-email
pnpm railway:deploy:scheduled-social-post

Optional: publish npm packages (SDK + CLI)

Skip this section when the release only changes the dashboard, API, or workers — npm users are unaffected.

When a release changes the public API (sdk/) or the CLI (agent/), publish after the API is live on production and after you commit the shipped code to main. Bump versions in the same release commits so git, tags, and npm stay aligned.

1. Pre-flight (feature commit)

Commit everything that Vercel already deployed (or will deploy):

git add -A
git commit -m "feat: …"
git push origin main

Match version in each package to the tag you will push. CI (.github/workflows/release.yml) publishes on tag push via npm trusted publishing.

SDK (@openquok/node-sdk) — bump sdk/package.json, then:

git add sdk/
git commit -m "chore(sdk): release 0.0.12"
git push origin main
git tag sdk-v0.0.12
git push origin sdk-v0.0.12

CLI (@openquok/auto-cli) — bump agent/package.json, then:

git add agent/
git commit -m "chore(cli): release 0.0.15"
git push origin main
git tag cli-v0.0.15
git push origin cli-v0.0.15

Preview release notes before tagging (from repo root):

pnpm release:notes sdk-v0.0.12
pnpm release:notes cli-v0.0.15

Full checklists: sdk/PUBLISHING.md and agent/PUBLISHING.md.

3. Manual publish (alternative)

If you are not using tag-driven CI, bump version in sdk/package.json and/or agent/package.json, commit and push to main, then from the monorepo root:

pnpm publish:sdk:build
pnpm publish:sdk:manual

pnpm publish:cli:build
pnpm publish:cli:manual

Requires npm login locally. Prefer tags + CI when trusted publishing is configured.

Next steps

Search documentation
Find a docs page
Discord Support