Deployment
Environment variables, migrations and hosting.
Payload Stack is a standard Next.js application with a database. It runs on Vercel, on any Node host, or in the included Docker image.
Environment variables
From .env.example:
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL | yes | Connection string for the adapter you chose |
PAYLOAD_SECRET | yes | Payload encryption and JWT secret |
BETTER_AUTH_SECRET | recommended | Falls back to PAYLOAD_SECRET. 32+ random characters. |
NEXT_PUBLIC_APP_URL | yes | Public origin, used for auth callbacks and email links |
RESEND_API_KEY, EMAIL_FROM | for email | Without them, emails are logged, not sent |
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, NEXT_PUBLIC_STRIPE_PRICE_* | for billing | See Billing |
<PROVIDER>_CLIENT_ID, <PROVIDER>_CLIENT_SECRET | per social provider | |
BLOB_READ_WRITE_TOKEN, S3_*, R2_*, AZURE_STORAGE_*, GCS_*, UPLOADTHING_TOKEN | for the storage adapter you chose | Without them uploads stay on local disk. See Media storage |
CRON_SECRET | for scheduled actions | Lets a clock run the job queue; without it that endpoint is admin-only. See Scheduled actions |
RUN_JOBS_IN_PROCESS | long-lived hosts only | true runs the queue in this process. Never on serverless. |
src/lib/env.ts validates them at boot and fails with the missing name.
Migrations
Generate a migration whenever collections change and run migrations during deploy:
pnpm db:migrate:create
pnpm db:migrate && pnpm buildVercel
Import the repository, set the variables above, use a managed PostgreSQL (Vercel Postgres, Neon, Supabase) and set the build command to pnpm db:migrate && pnpm build. Vercel's filesystem is ephemeral, so configure a storage adapter (Vercel Blob is the shortest path) or uploads vanish on the next deploy. Add the Stripe webhook endpoint after the first deploy.
Nothing runs between requests on Vercel, so a project with scheduled actions needs a clock: Payload Clock is free and runs every minute on any plan, and a vercel.json cron is the alternative (once a day on Hobby). Either way CRON_SECRET has to be set in the Vercel project as well as locally.
Docker
The included Dockerfile builds a standalone Next.js image. Provide the environment variables at runtime and run migrations before starting the container. This is the one place RUN_JOBS_IN_PROCESS=true belongs, if the project has scheduled actions — on one instance.
Checklist before launch
- An admin account exists (
/adminbootstrap is disabled once one does). auth.allowSignUpandauth.requireEmailVerificationare set as intended.- Legal pages reviewed in the admin (they are seeded placeholders).
- Stripe webhook endpoint created for production and the portal enabled.
NEXT_PUBLIC_APP_URLis the final domain (passkeys are bound to it).- Uploads go to a storage adapter, not local disk, unless the host has a persistent volume.
- Something runs the job queue, if the project has scheduled actions — the admin's Run queue button proves the endpoint works; a clock proves it keeps working.