L'application est à la racine du site : plateau en SVG, saisie au toucher (pion puis case d'arrivée, proposées à partir du moteur), boutons du jet, du videau et de nouvelle partie, coup de l'ordinateur affiché avec son temps, fin de partie, reprise depuis localStorage, aide lue dans les copies de docs/. Le moteur tourne dans le Web Worker existant ; main.ts est le seul assembleur (nouvelles règles dependency-cruiser). Le service worker met tout le site en cache, avec une empreinte du contenu comme version. Les pages de test du moteur passent sous /moteur/. Politique de sécurité du contenu dans le Caddyfile ; make test-browser joue une partie dans Chromium et Firefox sans écran (Playwright, hors de make test). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.0 KiB
Déploiement
Ustagammon est un site statique (PWA, ADR 0009) : des fichiers HTML,
JavaScript, le moteur en WebAssembly et ses données. L'application est à la
racine ; les pages de test du moteur de l'étape 0b restent publiées sous
/moteur/ (test du moteur) et /moteur/bench.html (mesure). Il est publié sur
CapRover, machine sans-pub (https://captain.cloud.sans.pub), app
ustagammon, sur https://ustagammon.sans.pub.
Le site est construit et testé sur le PC, pas sur le serveur. La
construction est lourde (Emscripten, génération des données du moteur) et déjà
outillée en local. make deploy-prod envoie à CapRover une archive qui
contient le site prêt, un Dockerfile et un Caddyfile (deploy/). Le serveur
ne fait que copier les fichiers dans une image Caddy (caddy:2.8.4-alpine),
qui les sert en HTTP derrière le HTTPS de CapRover.
Prérequis
- La chaîne d'outils du projet :
make setup. - CLI CapRover, installée avec Node par
fnm(le script la trouve seul) :eval "$(fnm env)"; fnm use lts-latest - Session CapRover valide. Le jeton expire ; pour vérifier :
En cas de
caprover api -n sans-pub -t /user/system/info -m GET -d '{}' -o falsenot valid anymore:caprover logindans un vrai terminal. - L'app
ustagammonexiste dans CapRover (créée le 2026-11-02) : sans volume (rien n'est stocké côté serveur), port du conteneur 80, domaineustagammon.sans.pubavec HTTPS forcé.
Publier
Depuis main, à jour avec origin/main (après fusion de la MR) :
make deploy-prod
Le script refuse de publier si l'arbre n'est pas propre, si l'on n'est pas sur
main, si main diffère d'origin/main, ou si la session CapRover a expiré.
Il lance make lint et make test, assemble le site (make package), puis
caprover deploy -t build/ustagammon.tar.
Pour une autre machine ou une autre app : CAPROVER_MACHINE=… CAPROVER_APP=… make deploy-prod.
Ce qui est publié
make siteassemblebuild/site/(9 Mo) :- le contenu de
web/à la racine : la page de l'application (index.html,app.css), le manifeste (manifest.webmanifest), les icônes (icons/), le service worker (sw.js), le Web Worker du moteur (engine-worker.mjs,engine-wasm.mjs) et les pages de test sousmoteur/; - l'application TypeScript compilée (
build/web/src/) sousapp/; - le moteur (
engine.mjs,engine.wasm,engine.data,positions.json) souswasm/; - des copies de
docs/glossaire/etdocs/scenarios/sousdocs/, lues par l'aide de l'application (ADR 0008) ; version.jsonavec le commit publié ;- enfin,
scripts/service-worker.shécrit en tête desw.jsla liste de tous ces fichiers et une empreinte de leur contenu.
- le contenu de
make packageajoutedeploy/et produitbuild/ustagammon.tar(environ 9 Mo, 7,3 Mo transférés grâce à la compression).tests/test_site.sh(dansmake test) construit l'image de production en local, la lance et vérifie ce que reçoit un navigateur : application, pages de test, aide, manifeste et icônes, liste du service worker, types MIME (application/wasmpour le moteur), compression gzip des données, en-têtes dont la politique de sécurité, et commit deversion.json.make test-browser(hors demake test, plusieurs minutes) joue une partie complète par l'interface dans Chromium et Firefox sans écran, sur la même image, puis vérifie la reprise, l'aide et le hors ligne.
Hors ligne et mises à jour. Le service worker met tous les fichiers du
site en cache à la première visite (environ 9 Mo), puis sert tout depuis ce
cache, avec ou sans réseau. À chaque publication, l'empreinte écrite dans
sw.js change dès qu'un fichier a changé : le navigateur, qui revérifie
sw.js à chaque ouverture, installe la nouvelle version (tout le site est
retéléchargé), qui prend la main et efface l'ancien cache. La page déjà
ouverte continue sur l'ancienne version ; le lancement suivant utilise la
nouvelle. Une publication sans changement de fichier garde le même sw.js :
rien n'est retéléchargé. Le service worker exige https (ou localhost) :
avec make deploy, en http sur le réseau local, l'application fonctionne,
mais pas hors ligne.
Réglages du serveur (deploy/Caddyfile) : compression zstd ou gzip, y compris
pour les données du moteur ; Cache-Control: no-cache (les noms de fichiers ne
changent pas d'une version à l'autre, le navigateur revalide chaque fichier) ;
X-Content-Type-Options: nosniff ; Referrer-Policy: no-referrer ; et une
politique de sécurité du contenu (Content-Security-Policy) : tout vient du
site lui-même, aucun script ni style en ligne, aucun eval, seule la
compilation du WebAssembly est permise ('wasm-unsafe-eval'). Elle est
vérifiée par tests/test_site.sh (en-tête présent) et par
make test-browser (aucune violation signalée par Chromium ni Firefox
pendant une partie).
Vérifier
curl -s https://ustagammon.sans.pub/version.json # commit publié
curl -sI https://ustagammon.sans.pub/wasm/engine.wasm # application/wasm
curl -sI https://ustagammon.sans.pub/ | grep -i content-security # CSP
curl -s https://ustagammon.sans.pub/sw.js | head -2 # version du cache
ssh sans.pub 'sudo docker service ps srv-captain--ustagammon --format "{{.Image}} {{.CurrentState}}" | head -2'
Puis ouvrir le site sur le téléphone : le plateau s'affiche et une consigne remplace « Chargement du moteur… ». La page de test du moteur (https://ustagammon.sans.pub/moteur/) doit afficher « Moteur prêt ».
Retour arrière
Dans CapRover, onglet Deployment de l'app ustagammon : redéployer une image
précédente (img-captain-ustagammon:N). Rien n'est stocké côté serveur : aucun
risque pour des données.
Incidents connus
Voir la-main-libre (docs/technique/deploiement.md) pour le registre Docker
de CapRover dont le certificat expire : le build réussit, l'envoi échoue, la
production n'est pas touchée ; redémarrer captain-registry puis relancer.