Major changes across backend, frontend, infrastructure: - Provider system with model selection (Google, DeepL, OpenAI, Ollama, Google Cloud) - Admin panel: user management, pricing, settings - Glossary system with CSV import/export - Subscription and tier quota management - Security hardening (rate limiting, API key auth, path traversal fixes) - Docker compose for dev, prod, and IONOS deployment - Alembic migrations for new tables - Frontend: dashboard, pricing page, landing page, i18n (en/fr) - Test suite and verification scripts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
151 lines
12 KiB
Markdown
151 lines
12 KiB
Markdown
# Story 6.5: Reverse Proxy (Traefik/Nginx)
|
||
|
||
Status: done
|
||
|
||
<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
||
|
||
## Story
|
||
|
||
En tant que **DevOps**,
|
||
je veux **un reverse proxy avec HTTPS**,
|
||
afin que **le trafic soit sécurisé et la charge répartie**.
|
||
|
||
## Acceptance Criteria
|
||
|
||
1. **Étant donné** Traefik ou Nginx est configuré
|
||
**Quand** les utilisateurs accèdent à l'application
|
||
**Alors** tout le trafic HTTP est redirigé vers HTTPS
|
||
**Et** TLS 1.2+ est appliqué
|
||
**Et** l'en-tête HSTS est défini
|
||
**Et** les routes `/api/*` sont acheminées vers le conteneur backend
|
||
**Et** les routes `/*` sont acheminées vers le conteneur frontend
|
||
|
||
## Tasks / Subtasks
|
||
|
||
- [x] Task 1 (AC: #1) — Choix et configuration du reverse proxy
|
||
- [x] 1.1 Choisir Traefik ou Nginx (un seul, cohérent avec l’existant si présent). Vérifier DEPLOYMENT_GUIDE.md et docker-compose existants.
|
||
- [x] 1.2 Ajouter le service reverse proxy dans le(s) fichier(s) Docker Compose de production (docker-compose.yml ou équivalent). Le proxy écoute sur 80/443 et transmet vers backend (ex. :8000) et frontend (ex. :3000).
|
||
- [x] 1.3 Configurer la redirection HTTP → HTTPS (301/308) et l’arrêt SSL (termination) sur le proxy.
|
||
- [x] Task 2 (AC: #1) — TLS et HSTS
|
||
- [x] 2.1 Configurer TLS 1.2+ uniquement (désactiver SSLv3, TLS 1.0/1.1). Certificats fournis par volume ou gestionnaire (ex. Let’s Encrypt).
|
||
- [x] 2.2 Ajouter l’en-tête HSTS (Strict-Transport-Security) avec max-age approprié (ex. 31536000) et includeSubDomains si pertinent.
|
||
- [x] Task 3 (AC: #1) — Routage /api/* et /*
|
||
- [x] 3.1 Règle : requêtes vers `/api` ou `/api/*` → backend (FastAPI, port interne ex. 8000). Préserver path et headers (X-Forwarded-For, X-Forwarded-Proto).
|
||
- [x] 3.2 Règle : requêtes vers `/` ou tout autre path → frontend (Next.js, port interne ex. 3000). Gérer SPA fallback si nécessaire (Next.js gère ses routes).
|
||
- [x] Task 4 — Documentation et santé
|
||
- [x] 4.1 Mettre à jour README.md et/ou DEPLOYMENT_GUIDE.md avec les instructions de déploiement derrière le proxy (variables, volumes pour certificats, commande up).
|
||
- [x] 4.2 Vérifier que le health check backend (/health) reste accessible via le proxy (ex. GET https://domain/api/v1/health ou /health selon montage).
|
||
|
||
## Dev Notes
|
||
|
||
- **Contexte** : Les stories 6-1 à 6-4 ont livré Docker Compose dev/prod, Redis, structlog. L’architecture impose un **reverse proxy (Traefik ou Nginx)** pour HTTPS/HSTS et termination SSL sur VPS (NFR8). La story 6-2 indique que la config du reverse proxy est hors scope de 6-2 et relève de cette story 6.5.
|
||
- **Architecture** : [Source: _bmad-output/planning-artifacts/architecture.md] — Infrastructure & Deployment : Reverse Proxy = Traefik ou Nginx ; HTTPS/HSTS ; termination SSL ; Hosting = VPS unique.
|
||
- **NFR8** : Chiffrement en transit — HTTPS obligatoire (TLS 1.2+). Le proxy termine TLS et communique en HTTP avec les conteneurs internes (réseau Docker).
|
||
- **Fichiers à toucher** : Fichiers Docker Compose production, configuration du proxy (dossier dédié type `docker/nginx/` ou `traefik/` selon choix), README/DEPLOYMENT_GUIDE, éventuellement .env.example pour options proxy (ex. ENABLE_HSTS).
|
||
|
||
### Project Structure Notes
|
||
|
||
- Racine projet : `office_translator/` avec `docker-compose.yml` (prod) et `docker-compose.dev.yml` (dev). Le reverse proxy doit être ajouté au Compose **production** uniquement ; en dev, accès direct backend :8000 et frontend :3000 reste acceptable. Si le projet a déjà un dossier `docker/nginx/` ou `nginx/` (voir DEPLOYMENT_GUIDE.md), réutiliser et compléter plutôt que dupliquer.
|
||
|
||
### References
|
||
|
||
- [Source: _bmad-output/planning-artifacts/architecture.md] — Infrastructure & Deployment (Reverse Proxy Traefik/Nginx, HTTPS/HSTS), NFR8.
|
||
- [Source: _bmad-output/planning-artifacts/epics.md] — Epic 6, Story 6.5, AC détaillées.
|
||
- [Source: _bmad-output/implementation-artifacts/6-2-docker-compose-production.md] — Compose prod, health checks, mention explicite que le reverse proxy est traité en 6.5.
|
||
- [Source: README.md] — Section Production Deployment (reverse proxy nginx/traefik, ENABLE_HSTS).
|
||
- [Source: DEPLOYMENT_GUIDE.md] — Nginx reverse proxy, SSL/TLS, ports 80/443, routage /api et frontend.
|
||
|
||
### Technical Requirements (Architecture Compliance)
|
||
|
||
- **Un seul proxy** : Traefik **ou** Nginx, pas les deux en production. Choix cohérent avec la doc existante (DEPLOYMENT_GUIDE mentionne Nginx ; si Traefik est préféré, documenter et utiliser Traefik partout).
|
||
- **TLS** : TLS 1.2 minimum ; désactiver TLS 1.0/1.1 et SSLv3. Certificats : volume monté (ex. `docker/nginx/ssl/`) ou intégration Let’s Encrypt (ex. Traefik ACME) selon préférence projet.
|
||
- **HSTS** : En-tête `Strict-Transport-Security` avec `max-age` ≥ 1 an recommandé ; `includeSubDomains` optionnel.
|
||
- **Routage** : `/api` et `/api/*` → backend (préserver path pour que FastAPI reçoive `/api/v1/...`) ; `/*` → frontend Next.js. Headers `X-Forwarded-For`, `X-Forwarded-Proto` (et si besoin `Host`) pour que l’app connaisse le schéma et l’IP réelle.
|
||
- **Health** : S’assurer que le health check (GET /health ou /api/v1/health) est accessible via le proxy pour les orchestrateurs et monitoring.
|
||
|
||
### Architecture Compliance
|
||
|
||
- Alignement avec architecture.md : reverse proxy Traefik ou Nginx pour production ; HTTPS obligatoire (NFR8) ; hébergement VPS.
|
||
- Ne pas exposer les ports backend/frontend directement sur l’hôte en prod si le proxy est en place (proxy seul sur 80/443, backend/frontend sur réseau interne Docker).
|
||
- Cohérence avec 6-2 : les services backend et frontend définis en 6-2 sont les upstreams du proxy ; pas de changement des ports internes sauf nécessité documentée.
|
||
|
||
### Library / Framework Requirements
|
||
|
||
- **Traefik** : image officielle `traefik:v3.x` ou v2.x (v2 LTS encore répandu). Configuration par labels Docker ou fichier static/dynamic. Pas de lib applicative côté backend/frontend pour le proxy.
|
||
- **Nginx** : image officielle `nginx:alpine` ou `nginx:latest`. Configuration dans un fichier `nginx.conf` (ou snippets) monté en volume. Modules standard suffisent (proxy_pass, ssl, headers).
|
||
- Aucune dépendance Python/Node supplémentaire pour cette story ; tout est configuration infra.
|
||
|
||
### File Structure Requirements
|
||
|
||
- **Docker Compose** : ajouter le service `nginx` ou `traefik` dans `docker-compose.yml` (prod). Dépendances : backend et frontend doivent être démarrés avant ou avec le proxy.
|
||
- **Config proxy** : soit dans un dossier dédié (`docker/nginx/`, `traefik/`, ou `nginx/`) avec fichiers `.conf` ou `traefik.yml`/`dynamic.yml`, soit configuration inline si minimale. Éviter de mettre des secrets en clair dans les fichiers versionnés (certificats dans .gitignore, montés par volume).
|
||
- **Documentation** : README.md et/ou DEPLOYMENT_GUIDE.md mis à jour avec la procédure de déploiement avec proxy (ports, variables, chemins certificats).
|
||
|
||
### Testing Requirements
|
||
|
||
- Vérifier en local ou sur environnement de préprod : accès à `http://localhost` (ou domaine de test) redirige vers `https://`.
|
||
- Vérifier que `https://domain/api/v1/health` (ou path health documenté) retourne 200 avec body JSON (status, database, redis, etc.).
|
||
- Vérifier que `https://domain/` sert la frontend (page d’accueil Next.js).
|
||
- Vérifier la présence de l’en-tête `Strict-Transport-Security` sur une réponse HTTPS.
|
||
- Optionnel : test TLS (ex. `openssl s_client -connect domain:443 -tls1_2`) pour confirmer TLS 1.2+.
|
||
|
||
### Previous Story Intelligence (6-4 Structlog Integration)
|
||
|
||
- **Fichiers créés/modifiés** : `core/logging.py`, `main.py`, middleware (security, api_key_auth, cleanup, error_handler), routes (deps, translate_routes, admin_routes), services (translation_service, storage_tracker, providers), `tests/test_logging.py`, `.env.example`, `.gitignore`.
|
||
- **Patterns établis** : configuration centralisée dans `core/` ; démarrage dans `main.py` ; variables d’environnement dans `.env.example`. Pas de changement des ports d’écoute backend (8000) ou frontend (3000) ; le reverse proxy de la story 6-5 doit simplement router vers ces ports.
|
||
- **Pour 6-5** : ne pas modifier la logique applicative backend/frontend. Uniquement ajout du service proxy et de sa configuration. Si le projet a déjà un `DEPLOYMENT_GUIDE.md` avec Nginx, réutiliser la structure (ex. `docker/nginx/nginx.conf`) et compléter pour TLS 1.2+, HSTS, et règles /api vs /*.
|
||
|
||
### Git Intelligence Summary
|
||
|
||
- La codebase contient déjà des références au déploiement (README.md, DEPLOYMENT_GUIDE.md, docker-compose dev/prod). Vérifier la présence de dossiers `docker/`, `nginx/`, ou `traefik/` et de fichiers de config existants avant d’en créer de nouveaux pour éviter doublons ou conflits.
|
||
|
||
### Latest Tech Information
|
||
|
||
- **Traefik 3.x** : configuration par providers (Docker, file). Labels Docker : `traefik.http.routers.*.rule`, `traefik.http.services.*`. TLS par entrypoints et certificats (fichiers ou ACME). HSTS via middleware `headers` (stsIncludeSubdomains, stsPreload, stsSeconds).
|
||
- **Nginx** : `ssl_protocols TLSv1.2 TLSv1.3;`, `ssl_prefer_server_ciphers off;` (TLS 1.3 préféré). HSTS : `add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;`. `proxy_pass` avec `http://backend:8000`, `proxy_set_header X-Forwarded-Proto $scheme;`.
|
||
- **Bonnes pratiques** : ne pas exposer les ports 8000/3000 sur l’hôte en prod quand le proxy est actif ; utiliser un réseau Docker dédié pour backend/frontend/proxy.
|
||
|
||
### Project Context Reference
|
||
|
||
- Aucun fichier `project-context.md` trouvé. Contexte : architecture.md (reverse proxy, NFR8), epics.md (Story 6.5), README.md (Production Deployment), DEPLOYMENT_GUIDE.md (Nginx, SSL/TLS, routage).
|
||
|
||
### Story Completion Status
|
||
|
||
- **Status** : ready-for-dev
|
||
- **Completion note** : Analyse de contexte et guide développeur complets — prêt pour implémentation.
|
||
|
||
## Dev Agent Record
|
||
|
||
### Agent Model Used
|
||
|
||
{{agent_model_name_version}}
|
||
|
||
### Debug Log References
|
||
|
||
- Nginx config validée manuellement (syntaxe). Pour test avec Docker : `docker run --rm -v $(pwd)/docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -v $(pwd)/docker/nginx/conf.d:/etc/nginx/conf.d:ro nginx:alpine nginx -t`
|
||
- Vérification manuelle recommandée : `curl -I http://localhost` (redirection vers HTTPS), `curl -k https://localhost/health`, `curl -k https://localhost/api/v1/languages` (si certificat auto-signé).
|
||
|
||
### Completion Notes List
|
||
|
||
- **Task 1–2** : Nginx était déjà présent dans docker-compose.yml (ports 80/443, volumes nginx.conf, conf.d, ssl). default.conf avait déjà HTTP→HTTPS (301), TLS 1.2/1.3, HSTS (max-age=31536000; includeSubDomains). Aucun changement au Compose.
|
||
- **Task 3** : Correction du routage `/api/` : suppression du `rewrite ^/api/(.*)$ /$1 break;` qui envoyait `/v1/...` au backend au lieu de `/api/v1/...`. Désormais le chemin complet est transmis (proxy_pass sans rewrite), FastAPI reçoit bien `/api/v1/...`. Routes `/*` déjà proxyfiées vers frontend.
|
||
- **Task 4** : DEPLOYMENT_GUIDE.md : ajout d’une sous-section « Reverse proxy (Nginx – Story 6.5) » décrivant HTTP→HTTPS, TLS 1.2+, HSTS, routage /api vs /*, health à /health. README.md : remplacement de « Docker Deployment (Coming Soon) » par un paragraphe pointant vers le Compose avec Nginx et DEPLOYMENT_GUIDE.
|
||
- **Code review (AI)** : CORS : ajout de X-API-Key dans Access-Control-Allow-Headers (nginx conf.d). Restriction de l’origine CORS (map dans nginx.conf : same-origin + localhost). Commentaire healthcheck nginx dans docker-compose + précisions dans DEPLOYMENT_GUIDE. README : précision ENABLE_HSTS (derrière Nginx, HSTS géré par le proxy). DEPLOYMENT_GUIDE : documentation de la route /translate et de la vérification du health via le proxy.
|
||
|
||
### File List
|
||
|
||
Pour cette story (6-5), seuls les fichiers ci-dessous ont été modifiés ; d’autres changements visibles dans le dépôt relèvent d’autres stories.
|
||
|
||
- docker/nginx/nginx.conf
|
||
- docker/nginx/conf.d/default.conf
|
||
- docker-compose.yml
|
||
- DEPLOYMENT_GUIDE.md
|
||
- README.md
|
||
|
||
## Change Log
|
||
|
||
| Date | Author | Action | Notes |
|
||
|------|--------|--------|-------|
|
||
| 2026-03-14 | Dev-story workflow | Implement | Routage /api/ corrigé (path préservé), doc Reverse proxy et Docker mise à jour. Story passée en review. |
|
||
| 2026-03-14 | Code-review workflow | Fix | CORS : X-API-Key dans Allow-Headers ; Origin restreint (map same-origin/localhost). Healthcheck nginx documenté ; ENABLE_HSTS et /translate documentés. File List et note périmètre Git mis à jour. |
|