# nginx.conf — reverse proxy + SPA static pour rubis-web # # Sert : # - / → assets SPA + index.html avec fallback try_files (TanStack Router) # - /api/* → reverse proxy vers le service ClusterIP rubis-api:3333 # - /ingest/* → reverse proxy vers PostHog EU (contourne les adblockers) # # Le service rubis-api est interne au cluster K3s (pas de NodePort). # Seul nginx (NodePort 30110 → Traefik) est exposé. upstream rubis_api { server rubis-api.rubis.svc.cluster.local:3333 max_fails=3 fail_timeout=10s; keepalive 32; } # PostHog ingestion endpoint (EU) — proxifié pour passer les adblockers # qui bloquent *.posthog.com directement. Le SDK est configuré avec # api_host: "/ingest" (cf. src/routes/__root.tsx). upstream posthog_ingest { server eu.i.posthog.com:443; keepalive 8; } # Assets PostHog (static.js, array.js, recorder) — domaine distinct chez PostHog. upstream posthog_assets { server eu-assets.i.posthog.com:443; keepalive 8; } # Compression gzip — Vite produit déjà du JS minifié, mais HTML/CSS/SVG # bénéficient toujours du gzip on-the-fly. gzip on; gzip_vary on; gzip_min_length 1024; gzip_types application/javascript application/json application/xml text/css text/html text/plain image/svg+xml; server { listen 80 default_server; server_name _; root /var/www; index index.html; # Limite raisonnable pour les uploads de factures (PDF, photos). client_max_body_size 25m; # Désactive les logs sur les ressources qui spamment (favicon, robots). location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; } # Assets fingerprintés Vite : cache long, immutable. location /assets/ { expires 1y; add_header Cache-Control "public, immutable"; try_files $uri =404; } # API → reverse proxy vers AdonisJS (rubis-api ClusterIP). # Inclut /api/v1/checkin/* qui sert les liens reçus par email. location /api/ { proxy_pass http://rubis_api; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Connection ""; # Timeouts adaptés au plus long endpoint (upload OCR Mistral). proxy_connect_timeout 5s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # PostHog assets (loader JS) — /ingest/static/* et /ingest/array/* vont # vers eu-assets.i.posthog.com (CDN). Doit être déclaré AVANT /ingest/ # car nginx matche par prefix le plus long. location ~ ^/ingest/(static|array)/ { rewrite ^/ingest/(.*)$ /$1 break; proxy_pass https://posthog_assets; proxy_http_version 1.1; proxy_set_header Host eu-assets.i.posthog.com; proxy_set_header Connection ""; proxy_ssl_server_name on; proxy_ssl_name eu-assets.i.posthog.com; } # PostHog ingestion (events, sessions, exceptions) — /ingest/* → eu.i.posthog.com location /ingest/ { rewrite ^/ingest/(.*)$ /$1 break; proxy_pass https://posthog_ingest; proxy_http_version 1.1; proxy_set_header Host eu.i.posthog.com; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Connection ""; proxy_ssl_server_name on; proxy_ssl_name eu.i.posthog.com; proxy_redirect off; } # SPA fallback : toute route non-asset, non-API → index.html # (TanStack Router gère côté client). location / { try_files $uri $uri/ /index.html; # index.html lui-même : pas de cache (pour récupérer les nouveaux # builds sans purger côté client). add_header Cache-Control "no-cache, no-store, must-revalidate"; } }