Conteneurisation (site 100 % statique — l'image ne détient AUCUNE donnée, vie privée identique) : - Dockerfile : nginxinc/nginx-unprivileged:alpine (uid 101, port 8080, pas de root), healthcheck wget intégré, labels OCI - nginx.conf : no-cache systématique (cohérence du jeu de fichiers à chaque mise à jour d'image, coût nul : ~600 Ko + gzip sur l'asset PK), gzip, en-têtes de sécurité, deny des dotfiles - .dockerignore : runtime uniquement (docs/ inclus — dialog changelog) ; local-test-data exclu en filet de sécurité - docker-compose.yml : read_only + tmpfs (/var/cache/nginx, /run, /tmp — les temporaires de nginx-unprivileged, constat au premier test réel) + no-new-privileges Nouveaux tests avant release : - scripts/container-test.sh : build + run DURCI (config compose) + healthcheck healthy + endpoints 200 + headers (no-cache/nosniff/DENY/ no-referrer) + gzip réel + MIME strict des modules ES + fichiers cachés non servis + image propre (pas de node_modules/npm) + docs/ embarqué + E2E playwright complet CONTRE LE CONTENEUR (HRT_E2E_BASE) - scripts/e2e.mjs : mode externe HRT_E2E_BASE (pilote un site déjà déployé — conteneur inclus, serveur local non démarré) - scripts/check.sh --release : supplée les 9 vérifications (version ↔ changelog ↔ tag ↔ arbre propre + test conteneur si daemon) Runtime Docker local installé pour le CI-like (colima 2 CPU / 2 Go) : premier build + run réel = 2 problèmes testés et corrigés (tmpfs /tmp, key case header_json curl). CONTAINER TEST OK en configuration durcie.
59 lines
3.0 KiB
Nginx Configuration File
59 lines
3.0 KiB
Nginx Configuration File
# ─────────────────────────────────────────────────────────────────────────────
|
||
# Config nginx du site HormoneTrack Web (conteneur — remplace le default.conf).
|
||
#
|
||
# La partie « serveur statique » est triviale ; les choix qui comptent :
|
||
#
|
||
# 1. **No-cache systématique** — raison : l'app est une SPA versionnée par un
|
||
# jeu de fichiers (index.html + modules ES + asset PK) qui doivent rester
|
||
# cohérents entre eux. Un cache client périmé AU MOMENT d'une mise à jour
|
||
# d'image = code JS ancien + changelog nouveau = état incohérent. Le site
|
||
# complet ≈ 600 Ko : le coût du re-téléchargement est négligeable sur un
|
||
# LAN/VPN, et la fraîcheur après mise à jour est garantie.
|
||
#
|
||
# 2. **gzip** — l'asset pk_profiles.json (550 Ko de floats) se compresse
|
||
# ~70 % : prend le seul fichier lourd en charge.
|
||
#
|
||
# 3. **En-têtes de sécurité minimaux** (site statique sans API, sans cookie,
|
||
# sans iframe légitime).
|
||
#
|
||
# Ce fichier est copié dans /etc/nginx/conf.d/default.conf (server block) par
|
||
# le Dockerfile — le http{} parent de l'image inclut déjà mime.types (.js
|
||
# servi en application/javascript : requis pour les modules ES).
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
server {
|
||
listen 8080;
|
||
listen [::]:8080;
|
||
server_name _;
|
||
|
||
root /usr/share/nginx/html;
|
||
index index.html;
|
||
|
||
# gzip : l'asset PK (550 Ko) se compresse ~4× — le seul fichier lourd
|
||
gzip on;
|
||
gzip_proxied any;
|
||
gzip_comp_level 5;
|
||
gzip_types application/json application/javascript text/css text/markdown text/plain;
|
||
|
||
# ── Headers appliqués à toutes les réponses ──────────────────────────────
|
||
# No-cache « always » : une mise à jour d'image est prise en compte au
|
||
# rechargement suivant, sans qu'aucun client conserve du code périmé.
|
||
add_header Cache-Control "no-cache, must-revalidate" always;
|
||
add_header X-Content-Type-Options "nosniff" always;
|
||
add_header X-Frame-Options "DENY" always;
|
||
add_header Referrer-Policy "no-referrer" always;
|
||
|
||
# ── Routing ─────────────────────────────────────────────────────────────
|
||
# SPA à fichier unique : pas de réécriture (le routing est par HASH
|
||
# `#chart` etc., jamais par chemin) — un simple fallback 404 suffit.
|
||
location / {
|
||
try_files $uri $uri/ =404;
|
||
}
|
||
|
||
# Défensif : ne jamais servir les fichiers cachés (.gitignore,
|
||
# .dockerignore — ils sont normalement exclus par .dockerignore, la
|
||
# règle reste en filet si quelqu'un build depuis une copie non propre).
|
||
location ~ /\. {
|
||
deny all;
|
||
}
|
||
}
|