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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user