Production Deployment
Production Deployment
The public deployment target is a self-hosted VPS running workbench, Postgres, HTTPS, Stripe billing endpoints, and public docs.
Required Production Environment
Set:
NEXT_PUBLIC_APP_URL=https://app.roleplay.sh
NEXT_PUBLIC_MARKETING_URL=https://roleplay.sh
NEXT_PUBLIC_DOCS_URL=https://docs.roleplay.sh
SUPPORT_EMAIL=support@roleplay.sh
DATABASE_URL=postgres://roleplay:<password>@postgres:5432/roleplay
ROLEPLAY_CLOUD_STORE_DRIVER=postgres
AUTH_SECRET=<strong-random-secret>
ROLEPLAY_AUTH_REQUIRED=true
STRIPE_SECRET_KEY=<stripe-secret>
STRIPE_WEBHOOK_SECRET=<stripe-webhook-secret>
STRIPE_BUILDER_PRICE_ID=<stripe-builder-price-id>
STRIPE_TEAM_PRICE_ID=<stripe-team-price-id>
ROLEPLAY_TRANSACTIONAL_EMAILS_ENABLED=false
AWS_REGION=<aws-region>
AWS_SES_FROM_EMAIL=<verified-ses-sender>
AWS_SES_FROM_NAME=Roleplay
AWS_SES_REPLY_TO_EMAIL=support@roleplay.sh
Keep ROLEPLAY_TRANSACTIONAL_EMAILS_ENABLED=false until the SES sender identity or domain is verified. When enabled, /api/readiness requires AWS_REGION and AWS_SES_FROM_EMAIL.
VPS Assets
The production bundle lives under:
infra/vps/
It includes:
- Dockerfile for the Next.js app
- Docker Compose stack
- Caddy reverse proxy config
- production environment example
Database Migration
The public production schema is in:
infra/postgres/migrations/
Run:
DATABASE_URL=postgres://roleplay:<password>@<host>:5432/roleplay pnpm db:migrate
The app can use Postgres-backed JSONB persistence by setting:
ROLEPLAY_CLOUD_STORE_DRIVER=postgres
The normalized tables are included for the production adapter path; cloud_state keeps the current Cloud behavior durable during launch.
Readiness Check
Use:
pnpm launch:readiness
curl https://app.roleplay.sh/api/readiness
/api/readiness reports required production env status and current Cloud health.
Stripe
Workbench billing uses:
/api/billing/checkout/api/billing/portal/api/stripe/webhook
Webhook events update workbench billing state when subscription metadata includes workspaceId.
Public Routes
Production DNS should route:
roleplay.shto the marketing/app entryapp.roleplay.shto workbenchdocs.roleplay.shto public docs
Smoke Test
After deploy, first run the non-mutating first-user preflight. It checks public copy, docs availability, readiness endpoints, and signed-out redirects without creating workspaces, projects, keys, runs, or findings.
bash scripts/smoke-production-first-user.sh
Then run the real end-to-end smoke with a real workspace and project:
- Confirm production starts empty unless a real workspace/project has been created.
- Choose Builder or Team through
https://app.roleplay.sh/start, then create the workspace from the plan confirmation screen. - Confirm internal app routes redirect signed-out visitors to sign-in.
- Create the first project and protected agent in onboarding.
- Copy the one-time project API key from onboarding or create a new key in Monitor.
- Run the included CLI locally against a local or staging target.
- Upload sanitized findings with the project ID and API key.
- Confirm Tests, Findings, and Evidence show uploaded evidence.
roleplay doctor --cloud --cloud-url https://app.roleplay.sh
roleplay upload latest --endpoint https://app.roleplay.sh --project <project-id> --api-key <project-api-key>
The upload command above requires values from the smoke-test project. Do not seed production with demo projects, runs, findings, or sample API keys.
The PowerShell helper scripts/verify-production-e2e.ps1 creates production workspace, project, API-key, run, and finding records. It is guarded by ROLEPLAY_ALLOW_PRODUCTION_TEST_DATA=true and should only be used when production test data has been explicitly approved.