feat(deploy): prod = LXC Proxmox + nginx-proxy-manager — COOKIE_SECURE/TRUST_PROXY=1 en prod (F1), REPRISE §5/§9 + README à jour

This commit is contained in:
Nicolas
2026-08-26 09:28:46 +02:00
parent 9262c3a4f2
commit ef9f04c551
3 changed files with 25 additions and 8 deletions
+10 -3
View File
@@ -28,9 +28,12 @@ SEICHE_ADMIN_USERNAME=admin SEICHE_ADMIN_PASSWORD='<≥12 caractères>' pnpm set
Puis ouvrir http://localhost:5173 et se connecter.
## Démarrage en production (Docker)
## Production (LXC Proxmox + nginx-proxy-manager)
Déploiement retenu (REPRISE.md §5 q12) : **LXC sur Proxmox** (Docker + compose dedans), TLS terminé par **nginx-proxy-manager** (Let's Encrypt).
```bash
# Dans le LXC :
docker compose up -d --build
# Premier compte (dans le conteneur, base vide) :
@@ -38,7 +41,11 @@ docker compose exec seiche sh -c \
"SEICHE_ADMIN_USERNAME=admin SEICHE_ADMIN_PASSWORD='<≥12 caractères>' pnpm setup"
```
Le conteneur écoute `8787` (API + front buildé, servi par Fastify). La base SQLite persiste dans le volume `seiche-data` (`/data`). Healthcheck : `GET /api/health`.
Puis dans NPM : **Add Site** → hostname (ex. `seiche.mondomaine.fr`), **Proxy to** `IP_DU_LXC:8787`, **Let's Encrypt** activé.
Le compose active `SEICHE_COOKIE_SECURE=1` + `SEICHE_TRUST_PROXY=1` (TLS + `X-Forwarded-For` derrière NPM). **Sans proxy TLS** (test Docker en LAN) : passer ces deux variables à `0`, sinon les cookies `Secure` ne sont pas envoyés en HTTP.
Le conteneur écoute `0.0.0.0:8787` (API + front buildé, servi par Fastify). La base SQLite persiste dans le volume `seiche-data` (`/data`). Healthcheck : `GET /api/health`.
## Variables d'environnement
@@ -69,7 +76,7 @@ Snapshot cohérente **en ligne** (`VACUUM INTO` dans le conteneur, le serveur co
- **Rate-limit** sur `/login` (anti brute-force, par IP client).
- Session : cookie **httpOnly + SameSite=Lax**, durée limitée, révocation au logout ; **CSRF** (double-submit) sur toutes les mutations.
- Secrets uniquement en variables d'environnement ; SQLite hors de l'image (volume + backup).
- **LAN sans TLS = mots de passe en clair sur le réseau.** À trancher (REPRISE.md §5 q4) : Caddy/Tailscale ou HTTP assumé. Derrière un proxy TLS : `SEICHE_COOKIE_SECURE=1` + `SEICHE_TRUST_PROXY=1`.
- **TLS** : en prod derrière nginx-proxy-manager (Let's Encrypt) → cookies `Secure` + `trustProxy` (déjà dans le compose). En dev LAN sans proxy : HTTP (mots de passe en clair, dév uniquement).
- API minimale : `/api/health` public, tout le reste protégé.
## Structure