Déploiement CapRover : site statique construit sur le PC, servi par Caddy #10

Merged
pierre merged 2 commits from deploiement into main 2026-11-02 20:05:12 +00:00
Owner

Pourquoi

Pierre a demandé de préparer le déploiement sur CapRover, comme pour les autres projets du Gitea, en particulier la-main-libre. Avec le socle PWA retenu (ADR 0009), Ustagammon est un site statique. Une fois publié sur https://ustagammon.sans.pub, n'importe qui pourra ouvrir l'application sur son téléphone, sans serveur sur le PC ni réseau local. C'est utile dès maintenant pour la page de test du moteur, et demain pour le plateau jouable (étape 0d.2) et les joueurs de l'Atelier du Huit.

Quoi

  • deploy/ : l'image de production. Un Dockerfile sur caddy:2.8.4-alpine (validé par Pierre), un Caddyfile et un captain-definition.

  • make site assemble build/site/ : web/ à la racine, le moteur sous wasm/, et version.json avec le commit publié.

  • make package produit l'archive envoyée à CapRover, build/ustagammon.tar (environ 9 Mo).

  • make deploy-prod (scripts/deploy.sh) publie main sur l'app ustagammon. Le script refuse de publier :

    • hors de main, avec des modifications non commitées, ou si main diffère d'origin/main ;
    • si la session CapRover a expiré.

    Il lance make lint et make test avant d'envoyer l'archive.

  • tests/test_site.sh (dans make test) : construit l'image de production en local, la lance et vérifie ce que reçoit un navigateur. Il contrôle les pages, les types MIME (application/wasm), la compression des données du moteur, les en-têtes, et que version.json donne le commit courant.

  • docs/deploiement.md : prérequis, publication, vérification, retour arrière, incidents connus.

  • CREDITS.md : Caddy (Apache-2.0).

Comment

la-main-libre fait construire son image par CapRover, sur le serveur, à partir du dépôt (caprover deploy -b main). Pour Ustagammon, la construction est lourde : Emscripten (image de 1,5 Go), génération des bases de fin de partie, et bientôt TypeScript. Tout cela est déjà outillé et testé sur le PC. Le site est donc construit en local, et CapRover ne reçoit qu'une archive (caprover deploy -t), dont il copie les fichiers dans une image Caddy. Le serveur ne compile rien, et ce qui est publié est exactement ce qui a été testé.

Le test du site a révélé deux pièges de Caddy, corrigés dans le Caddyfile :

  • Type MIME de engine.data : Caddy ne connaît pas l'extension .data et devinait text/xml d'après le début du fichier (la table d'équité). Le type application/octet-stream est maintenant imposé.
  • Compression : par défaut, Caddy ne compresse pas application/octet-stream. La liste des types compressés inclut maintenant ces 8,7 Mo de données, qui passent à 7,2 Mo.

Vérifié par la session principale :

  • make lint et make test : 9/9, dont test_site.sh ;
  • la page chargée à travers l'image de production, dans Chromium et Firefox sans interface : « Moteur prêt, chargé en 348 ms » (Chromium), 752 ms (Firefox).

Choix et compromis

  • Archive construite sur le PC plutôt que build sur le serveur : pas de chaîne de compilation sur le serveur, et ce qui est publié a passé les tests. En contrepartie, la publication part toujours du PC de Pierre, et pas d'un webhook Gitea.
  • Cache-Control: no-cache partout : les noms de fichiers ne changent pas d'une version à l'autre. Le navigateur revalide donc chaque fichier (ETag), au prix d'une requête par fichier à chaque visite. Le service worker de la PWA (étape 0d.2) gérera le hors ligne.
  • Pas de politique de sécurité du contenu (CSP) pour l'instant : le WebAssembly demande une règle particulière (wasm-unsafe-eval) à tester avec les vraies pages de l'application. Ce sera fait avec l'étape 0d.2.
  • make deploy garde son sens du contrat de CLAUDE.md (servir la page sur le réseau local). La publication est une cible distincte, make deploy-prod.

Risques et déploiement

  • Première publication : avec l'accord de Pierre, Claude Code crée l'app ustagammon dans CapRover, sans volume et sur le port 80, y attache ustagammon.sans.pub (le DNS pointe déjà vers le serveur), active le HTTPS et le force, puis lance make deploy-prod depuis main après la fusion de cette MR.
  • Rien n'est stocké côté serveur : un retour arrière ne met aucune donnée en jeu.
  • Le registre Docker de CapRover peut refuser l'envoi si son certificat a expiré (incident connu de la-main-libre). La production n'est alors pas touchée.

Retour arrière : dans CapRover, onglet Deployment de l'app, redéployer l'image précédente ; ou annuler le commit de fusion.

Comment vérifier

git switch main && git pull
make setup
make lint && make test        # dont tests/test_site.sh
make package && tar -tf build/ustagammon.tar | head

Après publication :

curl -s https://ustagammon.sans.pub/version.json
curl -sI https://ustagammon.sans.pub/wasm/engine.wasm

Hors périmètre

  • La politique de sécurité du contenu (CSP) et le service worker : étape 0d.2.
  • La publication automatique par webhook Gitea : écartée pour l'instant (construction lourde sur le serveur).

Generated with Claude Code https://claude.com/claude-code

## Pourquoi Pierre a demandé de préparer le déploiement sur CapRover, comme pour les autres projets du Gitea, en particulier `la-main-libre`. Avec le socle PWA retenu (ADR 0009), Ustagammon est un site statique. Une fois publié sur https://ustagammon.sans.pub, n'importe qui pourra ouvrir l'application sur son téléphone, sans serveur sur le PC ni réseau local. C'est utile dès maintenant pour la page de test du moteur, et demain pour le plateau jouable (étape 0d.2) et les joueurs de l'Atelier du Huit. ## Quoi - **`deploy/`** : l'image de production. Un `Dockerfile` sur `caddy:2.8.4-alpine` (validé par Pierre), un `Caddyfile` et un `captain-definition`. - **`make site`** assemble `build/site/` : `web/` à la racine, le moteur sous `wasm/`, et `version.json` avec le commit publié. - **`make package`** produit l'archive envoyée à CapRover, `build/ustagammon.tar` (environ 9 Mo). - **`make deploy-prod`** (`scripts/deploy.sh`) publie `main` sur l'app `ustagammon`. Le script refuse de publier : - hors de `main`, avec des modifications non commitées, ou si `main` diffère d'`origin/main` ; - si la session CapRover a expiré. Il lance `make lint` et `make test` avant d'envoyer l'archive. - **`tests/test_site.sh`** (dans `make test`) : construit l'image de production en local, la lance et vérifie ce que reçoit un navigateur. Il contrôle les pages, les types MIME (`application/wasm`), la compression des données du moteur, les en-têtes, et que `version.json` donne le commit courant. - **`docs/deploiement.md`** : prérequis, publication, vérification, retour arrière, incidents connus. - `CREDITS.md` : Caddy (Apache-2.0). ## Comment `la-main-libre` fait construire son image par CapRover, sur le serveur, à partir du dépôt (`caprover deploy -b main`). Pour Ustagammon, la construction est lourde : Emscripten (image de 1,5 Go), génération des bases de fin de partie, et bientôt TypeScript. Tout cela est déjà outillé et testé sur le PC. Le site est donc construit en local, et CapRover ne reçoit qu'une archive (`caprover deploy -t`), dont il copie les fichiers dans une image Caddy. Le serveur ne compile rien, et ce qui est publié est exactement ce qui a été testé. Le test du site a révélé deux pièges de Caddy, corrigés dans le `Caddyfile` : - **Type MIME de `engine.data`** : Caddy ne connaît pas l'extension `.data` et devinait `text/xml` d'après le début du fichier (la table d'équité). Le type `application/octet-stream` est maintenant imposé. - **Compression** : par défaut, Caddy ne compresse pas `application/octet-stream`. La liste des types compressés inclut maintenant ces 8,7 Mo de données, qui passent à 7,2 Mo. Vérifié par la session principale : - `make lint` et `make test` : 9/9, dont `test_site.sh` ; - la page chargée à travers l'image de production, dans Chromium et Firefox sans interface : « Moteur prêt, chargé en 348 ms » (Chromium), 752 ms (Firefox). ## Choix et compromis - **Archive construite sur le PC plutôt que build sur le serveur** : pas de chaîne de compilation sur le serveur, et ce qui est publié a passé les tests. En contrepartie, la publication part toujours du PC de Pierre, et pas d'un webhook Gitea. - **`Cache-Control: no-cache` partout** : les noms de fichiers ne changent pas d'une version à l'autre. Le navigateur revalide donc chaque fichier (ETag), au prix d'une requête par fichier à chaque visite. Le service worker de la PWA (étape 0d.2) gérera le hors ligne. - **Pas de politique de sécurité du contenu (CSP)** pour l'instant : le WebAssembly demande une règle particulière (`wasm-unsafe-eval`) à tester avec les vraies pages de l'application. Ce sera fait avec l'étape 0d.2. - **`make deploy` garde son sens du contrat de `CLAUDE.md`** (servir la page sur le réseau local). La publication est une cible distincte, `make deploy-prod`. ## Risques et déploiement - **Première publication** : avec l'accord de Pierre, Claude Code crée l'app `ustagammon` dans CapRover, sans volume et sur le port 80, y attache `ustagammon.sans.pub` (le DNS pointe déjà vers le serveur), active le HTTPS et le force, puis lance `make deploy-prod` depuis `main` après la fusion de cette MR. - **Rien n'est stocké côté serveur** : un retour arrière ne met aucune donnée en jeu. - **Le registre Docker de CapRover** peut refuser l'envoi si son certificat a expiré (incident connu de `la-main-libre`). La production n'est alors pas touchée. Retour arrière : dans CapRover, onglet *Deployment* de l'app, redéployer l'image précédente ; ou annuler le commit de fusion. ## Comment vérifier ``` git switch main && git pull make setup make lint && make test # dont tests/test_site.sh make package && tar -tf build/ustagammon.tar | head ``` Après publication : ``` curl -s https://ustagammon.sans.pub/version.json curl -sI https://ustagammon.sans.pub/wasm/engine.wasm ``` ## Hors périmètre - La politique de sécurité du contenu (CSP) et le service worker : étape 0d.2. - La publication automatique par webhook Gitea : écartée pour l'instant (construction lourde sur le serveur). Generated with Claude Code https://claude.com/claude-code
pierre added 2 commits 2026-11-02 20:05:11 +00:00
pierre merged commit f944debedd into main 2026-11-02 20:05:12 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: pierre/Ustagammon#10