Menu
Public documentation

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.sh to the marketing/app entry
  • app.roleplay.sh to workbench
  • docs.roleplay.sh to 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:

  1. Confirm production starts empty unless a real workspace/project has been created.
  2. Choose Builder or Team through https://app.roleplay.sh/start, then create the workspace from the plan confirmation screen.
  3. Confirm internal app routes redirect signed-out visitors to sign-in.
  4. Create the first project and protected agent in onboarding.
  5. Copy the one-time project API key from onboarding or create a new key in Monitor.
  6. Run the included CLI locally against a local or staging target.
  7. Upload sanitized findings with the project ID and API key.
  8. 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.