# Déploiement — PHI Conseil ## Cible Application Node.js (`next start`) derrière un reverse proxy TLS. Aucune base de données. Le build est statique pour toutes les pages ; seule `POST /api/contact` s'exécute à la demande. | Besoin | Valeur | | -------- | ---------------------------------------------------------------- | | Node.js | ≥ 20 (testé 26) | | RAM | ~150 Mo au repos | | Port | `PORT` (défaut 3000) | | Fichiers | `.next/`, `public/`, `content/`, `node_modules/`, `package.json` | ## Variables d'environnement Voir `.env.example`. En production : - `NEXT_PUBLIC_SITE_URL` — URL publique (canonical, sitemap, OG). **Inlinée au build** : rebuild si elle change. - `NEXT_PUBLIC_CONTENT_PREVIEW` — `0` en production. `1` affiche les témoignages de maquette avec un bandeau « exemple non vérifié » (sites de démonstration uniquement ; inlinée au build). - `CONTACT_TRANSPORT=smtp` + `CONTACT_TO`, `CONTACT_FROM`, `SMTP_HOST`, `SMTP_PORT`, `SMTP_SECURE`, `SMTP_USER`, `SMTP_PASS` — sans ces valeurs le formulaire fonctionne mais **n'envoie aucun courriel** (`CONTACT_TRANSPORT=log`) et l'utilisateur en est informé dans l'écran de confirmation. - `CONTACT_RATE_LIMIT` / `CONTACT_RATE_WINDOW_S` — anti-abus (défaut 5 / 600 s par IP). Le limiteur est en mémoire : valable pour une instance unique (PM2 `fork`). Pour plusieurs instances, brancher Redis dans `src/lib/security.ts`. Le proxy doit transmettre `X-Forwarded-For` (Caddy et nginx le font par défaut) pour que la limitation par IP soit correcte. ## Procédure générique (VPS / serveur Node) ```bash git clone phi-conseil && cd phi-conseil pnpm install --frozen-lockfile cp .env.example .env.local && $EDITOR .env.local pnpm build pm2 start pnpm --name phi-conseil -- start -p 3000 # ou systemd ``` Reverse proxy (exemple Caddy) : `phiconseil.example { reverse_proxy 127.0.0.1:3000 }` — Caddy obtient et renouvelle le certificat TLS automatiquement. HSTS est déjà émis par l'application. ### Vercel (alternative) Importer le dépôt, définir les variables d'environnement, framework Next.js détecté automatiquement. Le limiteur en mémoire n'est pas fiable en serverless : remplacer par Upstash/Redis ou le middleware de limitation du fournisseur. ## Procédure MacLustr (`mld`) — site de démonstration test.spboucher.ai 1. Manifeste `M1M32:~/dispatch/apps/phi-conseil.json` (dir `~/apps/phi-conseil`, PM2 `pnpm start -p 8520`, `tunnel.domain = test.spboucher.ai`, hooks `post_sync` : `pnpm install --frozen-lockfile && pnpm build`). 2. `mld stage ~/Desktop/phi-conseil phi-conseil` puis `mld deploy phi-conseil`. 3. DNS GoDaddy `A test.spboucher.ai → 51.161.112.61` (passerelle BHS64) — déjà en place ; `mld` pose la route Caddy et vérifie la santé publique. 4. Mises à jour : modifier **sur le nœud** (clone git), `pnpm build && pm2 restart phi-conseil`, puis `git commit/push` depuis le nœud (règle remote-first MacLustr). ## Sauvegardes et restauration - Le code et le contenu (`content/*.json`) sont versionnés dans Git : la sauvegarde est le dépôt distant. Restaurer = `git checkout ` + `pnpm install && pnpm build`. - Les messages du formulaire ne sont pas stockés par le site : ils vivent dans la boîte courriel destinataire (sauvegarde relevant du fournisseur de messagerie). - Secrets (`.env.local`) : conserver une copie chiffrée hors du dépôt (gestionnaire de mots de passe). ## Retour arrière 1. `git log` → identifier la dernière version saine (chaque mise en production est taguée `vX.Y.Z`). 2. `git checkout vX.Y.Z && pnpm install --frozen-lockfile && pnpm build && pm2 restart phi-conseil`. 3. Vérifier `GET /` (200) et `GET /api/contact` (405 attendu) ; sur MacLustr, `mld status --live phi-conseil`. ## Surveillance minimale - Santé : `GET /` doit répondre 200 (healthcheck PM2/mld). - Journaux : `pm2 logs phi-conseil` — les lignes `[contact]` ne contiennent qu'une empreinte d'IP, jamais le contenu des messages. - Erreurs de rendu : digest côté serveur (`console.error`) corrélable à l'écran d'erreur client. Un service d'erreurs (Sentry…) peut être ajouté dans `src/app/error.tsx` et `instrumentation.ts` ; non inclus par défaut pour éviter tout traceur non consenti. ## Mise à jour des dépendances `pnpm outdated` puis `pnpm update --latest` en suivant les notes de migration de Next.js ; relancer `pnpm check` et `pnpm test:e2e` avant mise en production. Audit : `pnpm audit`.