---
title: "Jah 4.0.24 : déployer à la main, et voir le papillon"
subtitle: "Un correctif de l’overlay de maintenance est parti en production sans le moindre workflow — image construite sur le serveur, puis `deploy.sh` avec backup et retour arrière. Et la preuve visible : la mue s’affiche pendant la mise à jour."
date: 2026-10-06
time: "02:24"
author: VFG
publishedBy: code
status: pub
tags: ["vfjah", "jah", "deploiement", "deploy", "agents"]
---

## TL;DR

Le correctif **BUG-PAPILLON** (l’overlay de maintenance ne s’affichait pas pendant une mise à jour)
était sur `main` depuis la 4.0.23, mais jamais en ligne. Les runners GitHub sont éteints (quota
d’Actions) : la chaîne habituelle tag → CI → image → deploy ne pouvait pas tourner. On l’a donc
faite **à la main**, jusqu’à `jah.vfg.lol` : 4.0.24 en production, `/readyz` confirmé,
`RestartCount=0`, repli armé. Et surtout — cette fois **on a vu la mue**.

## Le problème : corriger ne suffit pas, il faut livrer

Le 05/10, un agent avait corrigé le fond (`shutdown()` fermait toujours en `reason:'restart'`, donc
le client montrait le bandeau « Reconnexion… » au lieu de la chenille → cocon → papillon). Le test
d’intégration virait au vert, la PR était fusionnée. Mais sans CI, **`main` n’est pas la
production**. La version en ligne est restée 4.0.23 : correctif écrit, jamais servi.

## Ce qu’on a fait, dans l’ordre

1. **Bump 4.0.24** (`release --prepare` : `package.json`, `sw.js`, changelogs). Un patch, pas un
   tag — le tag reste une décision humaine pendant la pause des runners.
2. **Aligner `ops/*`** sur le serveur, et **vérifier par empreinte** : les cinq `sha256sum`
   (compose, deploy, env, jah, probe) sont identiques local ↔ serveur. Sans ce pas, un `deploy.sh`
   corrigé n’atteint jamais la prod.
3. **Construire l’image sur le serveur.** Le poste n’a pas Docker. On a donc envoyé une archive du
   source (`git archive`) au VPS et bâti `ghcr.io/fgdidou/jahmessenger:4.0.24` là-bas.
4. **Pousser l’image** vers GHCR — privé, donc il faut un jeton `write:packages`.
5. **Sonder à l’écart** avant de toucher la prod : conteneur jetable sur un volume à part →
   `/readyz` = `4.0.24`. (Le `/ws` en direct a donné 403 ; le même test sur l’image 4.0.23 en
   direct donnait 403 aussi — c’est l’environnement, pas le correctif. Via Caddy, la prod rend bien
   401.)
6. **Déployer** : `bash deploy.sh jah 4.0.24 --backup`. Backup vérifié, **voile posé avant l’arrêt**
   du hub en place, recréation, sonde `/readyz` + `/ws`, levée du voile. En cas d’échec, retour seul
   à 4.0.23 (l’image est déjà sur le serveur).

## Le moment qu’on voulait

`deploy.sh` pose la maintenance **avant** de recréer le hub. L’ancien (4.0.23) ferme donc les
sockets en `restart` — un simple bandeau. Le **nouveau** (4.0.24) ferme en `maintenance` : le client
affiche la mue. C’est exactement ce correctif, exercé en vrai.

Après le déploiement, on a posé la maintenance une minute sur la prod pour le voir de ses yeux :
chenille, cocon, papillon, message « Mise à jour en cours », puis retour tout seul. Le même test
avait été fait avant sur une copie locale des données de production, captures à l’appui.

## Ce que ça dit de la méthode

- **« Fusionné » ≠ « en ligne ».** Tant qu’il n’y a pas de CI, la distance entre `main` et la prod
  se mesure : `main` avait une version, le serveur une autre.
- **Hors CI, on reproduit les gardes à la main.** Backup avant prod, sonde avant et après, repli
  armé, empreintes des fichiers d’ops. Un « ça devrait marcher » n’est pas une preuve.
- **Un correctif ne se croit pas livré : il se voit.** Le test rouge → vert prouve la logique ; la
  mue à l’écran prouve que l’habitant en profite.

Live : **4.0.24**. Le papillon revient vite.