Déploiement
Variables d'env, Vercel, webhook Stripe, Cloudflare R2 et AUTH_TRUST_HOST.
Le boilerplate est pensé pour Vercel mais marche partout (Fly, Railway, Docker). Voici la checklist avant de pousser en prod.
Variables d'environnement requises
Toujours :
DATABASE_URL=postgres://...
# Auth.js
NEXTAUTH_SECRET= # openssl rand -base64 32
AUTH_URL=https://ton-domaine.com
AUTH_TRUST_HOST=true # CRITIQUE en prod derrière un proxy
# OAuth
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# Emails
RESEND_API_KEY=
EMAIL_FROM=noreply@ton-domaine.com
# Avatars (Cloudflare R2)
CLOUDFLARE_ACCOUNT_ID=
CLOUDFLARE_API_TOKEN=
R2_BUCKET=
R2_PUBLIC_URL=https://r2-public.ton-domaine.comVoir .env.example à la racine du projet pour la liste exhaustive (avec
les variables conditionnelles selon les modules choisis au CLI).
Selon les modules
Stripe
STRIPE_SECRET_KEY=sk_live_...
STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...Voir Webhooks Stripe pour la config côté Stripe Dashboard.
IA
ANTHROPIC_API_KEY=
OPENAI_API_KEY=
GEMINI_API_KEY=Ces clés peuvent aussi être renseignées depuis /admin/settings
(onglet IA) — chiffrées en DB. Les variables d'env restent prioritaires.
Upstash, Trigger.dev, PostHog, Sentry, OneSignal
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
TRIGGER_API_KEY=
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=
SENTRY_DSN=
ONESIGNAL_APP_ID=
ONESIGNAL_REST_API_KEY=
NEXT_PUBLIC_ONESIGNAL_APP_ID=Vercel
- Connecte ton repo, framework auto-détecté.
- Ajoute toutes les variables ci-dessus dans Settings → Environment Variables.
- Build command :
npm run build(par défaut). - Postgres : utilise un Neon dédié pour la prod (pas le même qu'en dev).
- Première fois : SSH dans une preview ou exécute en local avec
DATABASE_URLde prod :npx prisma db push - Crée le premier admin via
/setup(uniquement disponible si zéro user en DB) — supprime cette possibilité après en bloquant la route.
AUTH_TRUST_HOST
Obligatoire en prod derrière un proxy (Vercel, Cloudflare, Nginx, Fly...). Sans ça, Auth.js refuse les requêtes pour cause de host mismatch.
AUTH_TRUST_HOST=trueC'est aussi requis en LAN dev quand tu testes depuis un autre device (téléphone, autre PC).
Webhook Stripe — étape souvent oubliée
Après le déploiement :
- Stripe Dashboard → Developers → Webhooks → Add endpoint
- URL :
https://ton-domaine.com/api/billing/webhook - Sélectionne les events listés dans Webhooks Stripe
- Copie le Signing secret dans
STRIPE_WEBHOOK_SECRET - Redéploie (l'env var est lue côté serveur)
Sans ça, les paiements ne mettent pas à jour les Subscription en DB.
Cloudflare R2 — bucket public
Pour les avatars :
- Cloudflare Dashboard → R2 → Create bucket
- Settings → Public access → Custom Domains → ajoute un sous-domaine
(ex:
r2.ton-domaine.com). C'est leR2_PUBLIC_URL. - API Tokens → crée un token avec
Object Read & Writesur le bucket - Mets le token dans
CLOUDFLARE_API_TOKENet le bucket dansR2_BUCKET.
Premier admin (/setup)
Page seed accessible uniquement quand zéro user en DB. Visite
https://ton-domaine.com/setup, crée le compte. Une fois fait, la route
retourne 404 — pas besoin de la supprimer.
Checklist post-déploiement
-
/logincharge sans erreur - Inscription par email + verif marche
- OAuth GitHub/Google redirect correct (callback URLs OK)
- Magic link arrive (vérifier domaine Resend vérifié)
- Avatar upload fonctionne (R2 public URL accessible)
-
/adminaccessible pour le premier admin - Webhook Stripe test passé (Stripe Dashboard → Send test)
-
/maintenanceactivable depuis admin et désactivable
Allez plus loin
- Installation — setup local
- Webhooks Stripe — configuration détaillée
- Architecture —
proxy.tsetgetAppUrl