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.
35 lines
1.8 KiB
YAML
35 lines
1.8 KiB
YAML
# ─────────────────────────────────────────────────────────────────────────────
|
|
# docker-compose — un commandement pour tourner HormoneTrack Web.
|
|
#
|
|
# docker compose up -d → http://<hôte>:8080/
|
|
# docker compose up -d --build (rebuild après mise à jour du dépôt)
|
|
#
|
|
# Le conteneur ne détient AUCUNE donnée (site statique) : le volume n'est
|
|
# pas nécessaire, la persistance vit dans les navigateurs. Pas de variable
|
|
# d'environnement, pas de volume — la config = le code servi.
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
services:
|
|
web:
|
|
build: .
|
|
# Nom d'image stable : retaguer par version à chaque release sync si
|
|
# tu veux garder un historique (docker tag hormonetrack-web hormonetrack-web:vX.Y.Z)
|
|
image: hormonetrack-web:latest
|
|
container_name: hormonetrack-web
|
|
ports:
|
|
- "8080:8080" # port non privilégié de l'image unprivileged nginx
|
|
restart: unless-stopped
|
|
|
|
# ── Durcissement (site statique : AUCUNE écriture nécessaire) ───────────
|
|
# Filesystem en lecture seule + tmpfs pour les seuls dirs que nginx
|
|
# touche : l'image unprivileged place ses temporaires dans /tmp
|
|
# (proxy_temp, client_temp, pid) — sans ce tmpfs, nginx émerge
|
|
# « mkdir /tmp/proxy_temp failed (30: Read-only file system) » au
|
|
# démarrage avec read_only (constaté au premier container-test 8 sept.).
|
|
read_only: true
|
|
tmpfs:
|
|
- /var/cache/nginx
|
|
- /run
|
|
- /tmp
|
|
security_opt:
|
|
- no-new-privileges:true
|