Prood
Guides

Deployment

Deploy Prood applications to Vercel with Neon Postgres, Upstash Redis, and per-app configuration.

Prood deploys as separate Vercel projects sharing a single Neon Postgres database. Each app has its own environment variables and build configuration.

Production URL map (Prood)

URLApp
prood.comMarketing (apps/web)
dashboard.prood.comMerchant admin
api.prood.comCommerce API
checkout.prood.comHosted checkout
docs.prood.comDocumentation
admin.prood.comPlatform super-admin
{slug}.prood.appStorefront (wildcard on storefront project)
shop.client.comStore custom domain (per merchant)

Set NEXT_PUBLIC_PLATFORM_DOMAIN=prood.app for storefront subdomain resolution only. Platform services use *.prood.com via each app's BETTER_AUTH_URL and public URL env vars.

Deployment architecture

Drag to pan · Scroll to zoom

Prerequisites

  1. Vercel account with team/project access
  2. Neon Postgres provisioned (Vercel marketplace integration)
  3. Upstash Redis provisioned (Vercel marketplace integration)
  4. Payment provider accounts (Stripe, Easypay, and/or Ifthenpay)
  5. Domain names configured

Step 1 — Database setup

Run migrations against the production database once:

# Set DATABASE_URL to production Neon connection string
DATABASE_URL="postgresql://..." pnpm db:setup

This creates commerce schema + RLS + seed data, and pushes auth tables.

Step 2 — Deploy the API

The API must be deployed first — other apps depend on it.

SettingValue
FrameworkNext.js
Root directoryapps/api
Build commandcd ../.. && pnpm build --filter=api
Node.js version24

Environment variables

DATABASE_URL=postgresql://...
BETTER_AUTH_SECRET=<openssl rand -base64 32>
BETTER_AUTH_URL=https://api.prood.com
AUTH_COOKIE_DOMAIN=.prood.com
NEXT_PUBLIC_DASHBOARD_URL=https://dashboard.prood.com
API_PUBLIC_URL=https://api.prood.com
COMMERCE_CURRENCY=EUR
DEFAULT_PAYMENT_PROVIDER=stripe
STORAGE_PROVIDER=vercel-blob
BLOB_READ_WRITE_TOKEN=...
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
CHECKOUT_API_SECRET=<shared secret>
INTEGRATION_ENCRYPTION_KEY=<openssl rand -base64 32>
RESEND_API_KEY=re_...
RESEND_FROM_EMAIL="Prood <noreply@prood.com>"
NEXT_PUBLIC_PLATFORM_DOMAIN=prood.app

Step 3 — Deploy the storefront

SettingValue
Root directoryapps/storefront
Build commandcd ../.. && pnpm build --filter=storefront

Environment variables

DATABASE_URL=postgresql://...
COMMERCE_API_URL=https://api.prood.com/v1
BETTER_AUTH_SECRET=<same as API>
BETTER_AUTH_URL=https://storefront.example.com
CHECKOUT_URL=https://checkout.prood.com
CHECKOUT_API_SECRET=<same as API>
RESEND_API_KEY=re_...
RESEND_FROM_EMAIL="Prood <noreply@merchant-domain.com>"
DEFAULT_TENANT_ORG_ID=          # leave empty for multi-tenant
NEXT_PUBLIC_PLATFORM_DOMAIN=prood.app

Custom domains are added per-merchant via the dashboard Domains page.

Step 4 — Deploy the checkout app

SettingValue
Root directoryapps/checkout
Build commandcd ../.. && pnpm build --filter=checkout

Environment variables

UPSTASH_REDIS_REST_URL=https://...
UPSTASH_REDIS_REST_TOKEN=...
CHECKOUT_API_SECRET=<same as API>
CHECKOUT_URL=https://checkout.prood.com
COMMERCE_API_URL=https://api.prood.com/v1
STOREFRONT_URL=https://storefront.example.com
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_SECRET_KEY=sk_live_...
# Payment provider keys as fallbacks

Configure payment webhooks to: https://checkout.prood.com/api/webhooks/{provider}/{orgId}

Step 5 — Deploy the dashboard

SettingValue
Root directoryapps/dashboard
Build commandcd ../.. && pnpm build --filter=dashboard

Environment variables

DATABASE_URL=postgresql://...
COMMERCE_API_URL=https://api.prood.com/v1
BETTER_AUTH_SECRET=<same as API>
NEXT_PUBLIC_AUTH_URL=https://api.prood.com
INTEGRATION_ENCRYPTION_KEY=<same as API>
VERCEL_TOKEN=<for domain provisioning>
STOREFRONT_VERCEL_PROJECT_ID=<storefront project ID>
VERCEL_TEAM_ID=<team ID>
NEXT_PUBLIC_PLATFORM_DOMAIN=prood.app

Dashboard auth (sign-in, sign-up, organization ops) is issued by apps/api but proxied through the dashboard at /api/auth/* so session cookies stay on the dashboard origin. This is required on separate *.vercel.app preview URLs; with custom domains, set AUTH_COOKIE_DOMAIN=.prood.com on the API project so cookies are also shared across subdomains.

Step 6 — Deploy the platform admin

SettingValue
Root directoryapps/admin
Build commandcd ../.. && pnpm build --filter=admin

Environment variables

DATABASE_URL=postgresql://...
BETTER_AUTH_SECRET=<same as API>
BETTER_AUTH_URL=https://api.prood.com
NEXT_PUBLIC_AUTH_URL=https://api.prood.com
NEXT_PUBLIC_ADMIN_URL=https://admin.prood.com
ADMIN_USER_IDS=<comma-separated Better Auth user IDs>

apps/admin is for platform operations only. Keep it on a restricted domain and set ADMIN_USER_IDS before exposing it outside local development.

Step 7 — Deploy docs and web

AppRoot directoryNotes
docsapps/docsRuns sync:openapi at build time
webapps/webStatic marketing site
# Docs
NEXT_PUBLIC_DOCS_URL=https://docs.prood.com

# Web
NEXT_PUBLIC_WEB_URL=https://prood.com
NEXT_PUBLIC_DOCS_URL=https://docs.prood.com
NEXT_PUBLIC_DASHBOARD_URL=https://dashboard.prood.com
NEXT_PUBLIC_API_URL=https://api.prood.com
NEXT_PUBLIC_STOREFRONT_URL=https://demo-store.prood.app

Shared secrets

These must be identical across projects:

SecretApps
BETTER_AUTH_SECRETAPI, dashboard (SSR session validation), storefront
CHECKOUT_API_SECRETAPI, storefront, checkout
INTEGRATION_ENCRYPTION_KEYAPI, dashboard
DATABASE_URLAPI, storefront, dashboard, admin

Caching in production

The storefront uses Next.js Cache Components:

  • Catalog pages: 'use cache' with per-tenant tags
  • Cart/checkout/account: dynamic (cookie/session dependent)
  • Cache invalidation: dashboard product updates trigger revalidateTag via API

Production checklist

  • Strong secrets generated for BETTER_AUTH_SECRET, CHECKOUT_API_SECRET, INTEGRATION_ENCRYPTION_KEY
  • DEFAULT_TENANT_ORG_ID unset (multi-tenant) or set (single-tenant)
  • NEXT_PUBLIC_PLATFORM_DOMAIN configured
  • Upstash Redis provisioned for checkout
  • Payment webhooks pointed to checkout domain
  • Resend sender uses a verified production domain
  • pnpm db:setup run against production database
  • Custom domains verified for at least one merchant
  • SSL certificates active on all domains
  • ADMIN_USER_IDS set before deploying apps/admin

On this page