Production Deployment Checklist
app.neemias.app and api.neemias.app are production environments. Local
pnpm devis development-only. This checklist covers the full production setup — Cloudflare Dashboard + code.
1. Environment Variables — Cloudflare Dashboard
These must be set manually in the Cloudflare Dashboard. They are never committed.
Cloudflare Workers (api.neemias.app)
Navigate to Workers & Pages → neemias → Settings → Variables.
| Variable | Type | Required | Description |
|---|---|---|---|
AUTH_MODE | Plain text | Yes | Set to jwt. Default is dev (accepts any token — insecure). |
AUTH_JWT_SECRET | Secret | Yes | Generate with openssl rand -hex 32. Used to sign/verify JWT. |
ENVIRONMENT | Plain text | Yes | Set to production. Blocks dev-only endpoints like /api/v1/_seed. |
Optional (dev-mode tokens): For local development against the remote API:
AUTH_DEV_ADMIN_TOKEN— e.g.dev-admin-tokenAUTH_DEV_CALLER_TOKEN,AUTH_DEV_COORDENACAO_TOKEN, etc.
Cloudflare Pages (app.neemias.app)
Navigate to Workers & Pages → neemias-app → Settings → Environment Variables.
| Variable | Type | Required | Description |
|---|---|---|---|
DEPLOY_ENV | Plain text | Yes | Set to prod. Without this, the app's seed runs automatically. |
VITE_BACKEND_URL | Plain text | Yes | Set to https://api.neemias.app |
2. Deploy Pipeline
bash
# 1. Frontend — build + Pages auto-deploy
pnpm build:app
git add -A && git commit -m "..."
git push
# → Cloudflare Pages builds and deploys automatically
# 2. Worker — direct deploy
pnpm deploy:worker
# 3. Apply D1 migrations (if any)
pnpm db:migrate:remoteWhat build:app does (v0.54.0+)
- Exports
NODE_ENV=productionsogenerate-headers.tsuses production CSP - Runs
scripts/generate-headers.tsviaapp/csp.config.ts— writes CSP intoapp/public/_headers - Runs Vite production build (Rolldown bundler)
- Output goes to
app/dist/. Pages serves from this directory
CSP note: Production CSP uses edge-generated dynamic nonces via Pages Middleware (functions/_middleware.ts). See security docs for details.
3. Security Checklist
- [ ]
AUTH_MODE=jwt(notdev) - [ ]
AUTH_JWT_SECRETis a strong random value stored as a Secret - [ ]
ENVIRONMENT=production(blocks seed endpoint) - [ ]
DEPLOY_ENV=prod(on Pages — blocks frontend seed) - [ ] CSP mode is correct for production (dynamic nonces)
- [ ]
NODE_ENV=productionexported duringpnpm build:app - [ ]
scripts/pre-deploy-check.shexits 0 - [ ]
scripts/validate-csp.shpasses - [ ]
frame-ancestors 'none'in CSP - [ ]
Strict-Transport-Security: max-age=63072000active - [ ] No dev-mode tokens exposed in production
- [ ] All D1 migrations applied (
pnpm db:migrate:remote) - [ ] Rollback tag identified (previous
v*tag for quick revert) - [ ] Visual smoke test: login page loads, no CSP console errors