Deployment
The app deploys as a single Vercel project. Payload admin, Next.js frontend, and API routes all run in the same deployment.
The production build should run migrations first, then compile the app:
If the migration fails, the build fails and Vercel will not deploy a broken release.
For local development, use the repo scripts:
migrate:create generates migration files from schema changes.
migrate applies pending migration files to your database.
Services
| Service | Role | Setup |
|---|---|---|
| Vercel | Hosting + serverless functions | Connect GitHub repo |
| Neon | Postgres database | Vercel integration or manual |
| Vercel Blob | Audio files, saint images | Vercel integration |
Vercel setup
- Push the repo to GitHub
- Go to vercel.com → Add Project → import
app_saintete - Set the Root Directory to
.(repo root — there is no separate Next.js subfolder) - In Build & Development Settings, override the Build Command with
payload migrate && next build - Add environment variables (see below)
- Deploy
Vercel auto-deploys on push to main.
Environment variables
Set these in Vercel → Project → Settings → Environment Variables.
| Variable | Where to get it |
|---|---|
DATABASE_URI |
Neon dashboard → Connection string (pooled) |
PAYLOAD_SECRET |
Any long random string — generate once, never change |
NEXT_PUBLIC_VAPID_PUBLIC_KEY |
Run npx web-push generate-vapid-keys |
VAPID_PRIVATE_KEY |
Same command as above |
VAPID_SUBJECT |
mailto:your@email.com |
Warning
PAYLOAD_SECRET must be consistent across deployments. Changing it invalidates all admin sessions.
Note
Vercel exposes DATABASE_URL during the build, and Payload also accepts it. Locally, this repo uses DATABASE_URI in the environment examples.
Neon database
- Create a project at neon.tech
- Use the Vercel integration for automatic
DATABASE_URIinjection, or copy the connection string manually - Use the pooled connection string (port 6543) for serverless functions
In this project, migrations are applied by the build command (payload migrate && next build).
For local verification, run npm run migrate manually before pushing.
First migration workflow
Use this when the database is still empty and you want to create the initial migration history.
- Reset the Neon dev branch from the parent so it is empty again.
- Point
DATABASE_URIlocally to that empty branch. - Run
npx payload migrate:createand name the migrationinitialwhen prompted. - Run
npx payload migratelocally to apply it and verify the tables appear in Neon. - Commit the
migrations/directory and push it.
From that point on, every Vercel build runs payload migrate && next build, so the first deployment creates the schema and the following ones only apply missing migrations.
Migration when content changes
Whenever you change a collection or field:
- Update the Payload config.
- Run
npm run migrate:create -- <name>to generate a new migration. - Run
npm run migratelocally to test the change. - Commit both the code change and the new migration files.
Common mistake:
- npm run payload migrate:refresh fails here because migrate:refresh is not defined in package.json.
- Use npm run migrate:create -- <name> and npm run migrate.
Do not add migrations/ to .gitignore. That folder is part of the schema history.
First deploy checklist
- [ ]
DATABASE_URIset and database reachable - [ ]
PAYLOAD_SECRETset - [ ] VAPID keys set (all three variables)
- [ ] Vercel build command set to
payload migrate && next build - [ ]
migrations/committed - [ ] Deployed successfully
- [ ] Visit
/admin/create-first-userto create the admin account (one-time) - [ ] Add at least one godchild and verify their URL loads
Custom domain
Set in Vercel → Project → Domains. Godchild URLs use whatever domain you configure there.
GitHub Pages (docs only)
Docs are deployed automatically by the CI workflow (.github/workflows/docs.yml) on every push to main that touches docs/ or mkdocs.yml. The built site is pushed to the gh-pages branch.
Enable GitHub Pages in: repo Settings → Pages → Source: Deploy from branch → gh-pages / / (root).
Docs URL: https://dorianhgn.github.io/app_saintete