Aller au contenu

Déploiement courant de CMonChoix Platform

Status: CURRENT / RELEASE AUTHORITY / 2026-09-16

Cette procédure est l'autorité opérationnelle actuelle pour préparer, prévalider, déployer et certifier une release CMonChoix. Les procédures P0/P1 plus anciennes restent des preuves historiques et ne doivent pas être utilisées comme autorité live sans revalidation.

Autorités

  1. GitHub main fournit le SHA source certifié.
  2. /mnt/data/cmonchoix-release-authority/<SHA> est le worktree de release immuable utilisé pour les opérations.
  3. Le docker-compose.yml de cette release définit les images et le contrat Compose.
  4. Les images de production sont épinglées par RepoDigest.
  5. /mnt/data/cmonchoix-platform/.env reste hors Git et fournit secrets/configuration live.
  6. Le checkout /mnt/data/cmonchoix-platform n'est ni une zone de build ni l'artefact de release.

Un checkout live en retard sur GitHub n'est pas à lui seul un défaut. Il ne faut pas le reset --hard pour le rendre artificiellement égal au SHA déployé.

Préparation de la release

Préparer ou revalider le worktree avec l'autorité versionnée :

CCX_TARGET_SHA=<SHA_COMPLET_CERTIFIE> \
CCX_RELEASE_SOURCE_REPO=/mnt/data/cmonchoix-platform \
CCX_RELEASE_BASE=/mnt/data/cmonchoix-release-authority \
bash scripts/release-authority-prepare.sh

Marqueur attendu :

CCX_RELEASE_AUTHORITY_PREPARE=PASS

Le worktree obtenu doit être détaché, propre et exactement sur le SHA demandé.

Préflight worker

SHA=<SHA_COMPLET_CERTIFIE>
RELEASE=/mnt/data/cmonchoix-release-authority/$SHA

CCX_TARGET_SHA="$SHA" \
CCX_RELEASE_ROOT="$RELEASE" \
bash "$RELEASE/scripts/platform-worker-safe-deploy.sh" preflight

Le préflight est bloquant. Il vérifie notamment :

  • checkout live Git propre ;
  • WordPress Core absent de l'hôte ;
  • .env présent en 0600 et contrat DB explicite ;
  • backup offsite suffisamment récent et réussi ;
  • worktree de release propre et sur le SHA exact ;
  • Compose valide et sans build applicatif ;
  • image worker locale et épinglée par digest ;
  • WordPress, MariaDB et Redis healthy ;
  • worker courant identifiable ;
  • CCX_ACTIVE_FEEDS présent, non vide, normalisé et composé d'identifiants valides ;
  • pour chaque feed actif, ccx sync doctor sans lock ni row claim.

Un seul feed actif occupé suffit à refuser le rollout.

Rollout ciblé du worker

Après préflight vert :

CCX_TARGET_SHA="$SHA" \
CCX_RELEASE_ROOT="$RELEASE" \
bash "$RELEASE/scripts/platform-worker-safe-deploy.sh" deploy

Le rollout reste limité à platform-worker et utilise les garde-fous équivalents à :

--no-deps --no-build --pull never

Interdictions :

  • docker compose down ;
  • docker compose up --build ;
  • --remove-orphans pour ce rollout ;
  • prune/suppression de volumes ;
  • build improvisé sur le VPS ;
  • tag flottant comme autorité d'image ;
  • reset/switch du checkout live comme mécanisme de déploiement.

Rollback

Avant mutation, le safe-deploy conserve sous :

~/.local/state/cmonchoix/deployments/<timestamp>/

au minimum l'image précédente, les Compose précédents avec leurs hashes, le working directory, mounts, networks, IDs des services stateful, SHA cible et feeds actifs.

Après démarrage de la mutation, une erreur déclenche le rollback automatique du worker. WordPress, MariaDB et Redis doivent conserver leurs IDs.

Rollback manuel d'une preuve encore valide :

CCX_ROLLBACK_DIR=<deployment-state-directory> \
bash "$RELEASE/scripts/platform-worker-safe-deploy.sh" rollback

Ne pas rejouer directement une archive historique de recovery sans nouvelle décision de recovery et revalidation des dépendances.

Vérification post-rollout

Le worker cible doit :

  • exécuter exactement le RepoDigest du Compose ciblé ;
  • être running ;
  • conserver exactement les deux mounts mutables uploads/runtime-spool ;
  • ne pas monter /var/www/html depuis l'hôte ;
  • passer wp core version, wp core is-installed et wp ccx --help ;
  • exposer la même autorité CCX_ACTIVE_FEEDS que le worker pré-rollout ;
  • passer ccx sync status --feed=<feed> --limit=1 et ccx sync doctor --feed=<feed> pour chaque feed actif ;
  • passer ccx health projections ;
  • laisser WordPress, MariaDB et Redis inchangés ;
  • laisser le checkout live propre et sans WordPress Core.

Runtime Guard v2

Après un changement runtime significatif, la certification finale utilise toujours les fichiers de la release :

CCX_LIVE_ROOT=/mnt/data/cmonchoix-platform \
CCX_GUARD_COMPOSE_FILE="$RELEASE/docker-compose.yml" \
bash "$RELEASE/scripts/runtime-readonly-guard.sh" --runtime

Verdict attendu :

RUNTIME_GUARD_FAILURES=0
RUNTIME_GUARD_WARNINGS=0
RUNTIME_GUARD_STATUS=PASS
CCX_RUNTIME_GUARD_V2_RUNTIME=PASS

Ne pas exécuter le guard d'un checkout historique contre un worker plus récent puis interpréter le mismatch comme une panne de production.

Synchronisation marchands / systemd

L'autorité CURRENT est un scheduler générique unique, versionné sous :

operations/systemd/ccx-active-feeds-sync.service
operations/systemd/ccx-active-feeds-sync.timer

Le service appelle uniquement :

wp ccx sync active-feeds

Il ne contient aucun identifiant marchand. Le set planifié est dérivé dans le worker de CCX_ACTIVE_FEEDS via le registry/runtime canonique.

Le timer démarre la séquence quotidienne à 03:15 UTC avec Persistent=true et RandomizedDelaySec=10m. Les feeds actifs sont ensuite exécutés séquentiellement par le Sync Runner. Les anciens timers Samsung 03:15 et Acer 04:15 sont RETIRED et ne doivent pas coexister avec l'autorité générique.

La migration, la validation détaillée et le rollback sont définis dans Active Feeds Daily Sync.

Certification minimale du scheduler

systemd-analyze verify \
  "$RELEASE/operations/systemd/ccx-active-feeds-sync.service" \
  "$RELEASE/operations/systemd/ccx-active-feeds-sync.timer"

sha256sum \
  "$RELEASE/operations/systemd/ccx-active-feeds-sync.service" \
  /etc/systemd/system/ccx-active-feeds-sync.service \
  "$RELEASE/operations/systemd/ccx-active-feeds-sync.timer" \
  /etc/systemd/system/ccx-active-feeds-sync.timer

systemctl is-enabled ccx-active-feeds-sync.timer
systemctl list-timers ccx-active-feeds-sync.timer --all --no-pager

Les hashes release/installés doivent être identiques. ccx-active-feeds-sync.timer doit être la seule autorité de planification marchands activée.

Références