# Story 6.5: Reverse Proxy (Traefik/Nginx) Status: done ## 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. |