docs: READMEs racine + server + web (E1) — dev, prod, env, backup, sécurité
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# Seiche
|
||||
|
||||
Appli web auto-hébergée, **réseau local uniquement, mono-utilisateur** : gère un service externe via son API REST, protégée par mot de passe.
|
||||
|
||||
**Stack** : TypeScript strict · Node 22 + Fastify 5 · SQLite (libsql + Drizzle) · Vite + React 19 + Tailwind 4 · 1 conteneur (API + front statique).
|
||||
|
||||
- Doc de projet / décisions / plan : [REPRISE.md](REPRISE.md)
|
||||
- Détail backend : [server/README.md](server/README.md) · Détail front : [web/README.md](web/README.md)
|
||||
|
||||
## Prérequis
|
||||
|
||||
- Node ≥ 22, pnpm (workspace)
|
||||
- Docker + compose (pour la prod)
|
||||
|
||||
## Démarrage en développement
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm dev:server # terminal 1 — API sur http://localhost:8787
|
||||
pnpm dev:web # terminal 2 — Vite sur http://localhost:5173 (proxy /api → 8787)
|
||||
```
|
||||
|
||||
Premier compte (nécessaire une seule fois, idempotent) :
|
||||
|
||||
```bash
|
||||
SEICHE_ADMIN_USERNAME=admin SEICHE_ADMIN_PASSWORD='<≥12 caractères>' pnpm setup
|
||||
```
|
||||
|
||||
Puis ouvrir http://localhost:5173 et se connecter.
|
||||
|
||||
## Démarrage en production (Docker)
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
|
||||
# Premier compte (dans le conteneur, base vide) :
|
||||
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`.
|
||||
|
||||
## Variables d'environnement
|
||||
|
||||
Référent complet : [.env.example](.env.example) (copier dans `.env` pour la dev — **jamais committer le `.env`**).
|
||||
|
||||
| Variable | Défaut | Rôle |
|
||||
|---|---|---|
|
||||
| `SEICHE_PORT` / `SEICHE_HOST` | `8787` / `127.0.0.1` | Écoute du serveur (Docker force `0.0.0.0`) |
|
||||
| `SEICHE_DATA_DIR` | `./data` | Dossier SQLite (volume `/data` en Docker) |
|
||||
| `SEICHE_SESSION_TTL_MS` | 8 h | Durée de vie d'une session |
|
||||
| `SEICHE_SESSION_ABSOLUTE_TTL_MS` | 7 j | Durée absolue max |
|
||||
| `SEICHE_MAX_LOGIN_ATTEMPTS_PER_MINUTE` | `5` | Rate-limit `/login` par IP |
|
||||
| `SEICHE_COOKIE_SECURE` | `0` | `1` derrière un proxy TLS (cookies `Secure`) |
|
||||
| `SEICHE_TRUST_PROXY` | `0` | `1` derrière un proxy (lit `X-Forwarded-For`) |
|
||||
| `SEICHE_EXTERNAL_*` | `example` | Service REST externe (adaptateur, URL, clé, cache…) |
|
||||
|
||||
## Sauvegarde
|
||||
|
||||
```bash
|
||||
./scripts/backup.sh [dir_sortie] # défaut : ./backups/
|
||||
```
|
||||
|
||||
Snapshot cohérente **en ligne** (`VACUUM INTO` dans le conteneur, le serveur continue de servir) → copie **hors** du volume → vérification de l'en-tête SQLite. Prérequis : conteneur en marche. Penser à cronner et à stocker les `.db` ailleurs que sur la machine (le dossier `backups/` est gitignoré).
|
||||
|
||||
## Sécurité — non négociables
|
||||
|
||||
- Mot de passe **Argon2id** (sel par compte), jamais en clair ni dans les logs.
|
||||
- **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`.
|
||||
- API minimale : `/api/health` public, tout le reste protégé.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
seiche/
|
||||
├── server/ # Fastify : routes /api/v1/*, auth, DB, client externe
|
||||
├── web/ # Vite + React : login, dashboard, client API
|
||||
├── scripts/ # backup.sh
|
||||
└── docker-compose.yml · Dockerfile · .env.example
|
||||
```
|
||||
Reference in New Issue
Block a user