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.
42 lines
2.7 KiB
Docker
42 lines
2.7 KiB
Docker
# ─────────────────────────────────────────────────────────────────────────────
|
|
# HormoneTrack Web — image de déploiement Docker (site statique, 100 % local).
|
|
#
|
|
# POURQUOI C'EST SIMPLE : l'app n'a AUCUN build (ES modules natifs) et AUCUN
|
|
# composant serveur — « conteneuriser » = servir les fichiers avec nginx.
|
|
# Le conteneur ne détient AUCUNE donnée : tout vit dans le localStorage des
|
|
# navigateurs clients (le serveur ne fait que distribuer des fichiers, cf
|
|
# docs/DEVELOPPEMENT.md §10 — la vie privée est inchangée).
|
|
#
|
|
# Choix d'image : `nginx-unprivileged` (utilisateur 101, port 8080, écritures
|
|
# limitées à /tmp) — meilleure pratique conteneur (pas de root), même image
|
|
# que pour un self-host NAS/VPS. Alpine = ~50 Mo décompressé.
|
|
#
|
|
# Build : docker build -t hormonetrack-web .
|
|
# Run : docker run -p 8080:8080 hormonetrack-web (ou docker compose up -d)
|
|
# Cf docs/DEVELOPPEMENT.md §10 « Déploiement ».
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
FROM nginxinc/nginx-unprivileged:alpine
|
|
|
|
# ── Métadonnées OCI (traçabilité du conteneur déployé) ───────────────────────
|
|
LABEL org.opencontainers.image.title="HormoneTrack Web" \
|
|
org.opencontainers.image.description="Suivi de thérapie hormonale — app web 100 % locale (site statique). Portage navigateur de l'app Android." \
|
|
org.opencontainers.image.source="https://gitea.cloudyfy.fr/Siphonight/HormoneTrack-web" \
|
|
org.opencontainers.image.licenses="GPL-3.0"
|
|
|
|
# ── Config nginx spécifique (port non-privilégié, no-cache, gzip, sécurité) ──
|
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
|
|
# ── Fichiers du site ────────────────────────────────────────────────────────
|
|
# Tout le dépôt SAUF ce qui n'est pas runtime (tests, scripts, npm) — cf
|
|
# .dockerignore. ⚠️ docs/ DOIT rester dans l'image : le dialog « Nouveautés »
|
|
# fetch docs/CHANGELOG.md au démarrage.
|
|
COPY . /usr/share/nginx/html/
|
|
|
|
# Le site est statique : le healthcheck synthétique vérifie que nginx répond
|
|
# (busybox wget est présent dans l'image alpine).
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD wget -q -O /dev/null http://127.0.0.1:8080/ || exit 1
|
|
|
|
# Port non privilégié (l'image unprivileged n'a pas le droit de binde <1024)
|
|
EXPOSE 8080
|