12 KiB
Bilan de la mission de déploiement — Syllabus
Mission : docs/prompt-deploiement-paillasse.md, étapes 1 à 16, exécutée du
2026-10-07 au 2026-10-12 sur la Dedibox 163.172.4.195 (Debian 12, Xeon
D-1531, 32 Go, RAID 1). Le détail de chaque étape (commandes, problèmes,
explications) est dans docs/journal.md ; ce document en est la synthèse.
Ce qui fonctionne, avec la preuve de chaque critère
| Étape | Critère | Preuve (journal) |
|---|---|---|
| 1. Reconnaissance | Inventaire, KVM, version de Kolla justifiée | docs/inventaire-serveur.md ; /dev/kvm présent ; Kolla 2025.2, seule série maintenue qui supporte Debian 12 (ADR 0001) |
| 2. Durcissement | Clé OK, mot de passe et root refusés, seuls 22/80/443 | Permission denied (publickey) pour le mot de passe et pour root ; nmap depuis le Mac : 22 seul ouvert (80/443 autorisés, rien n'écoutait encore) |
| 3. Sauvegardes | Une sauvegarde envoyée, un fichier restauré | quotidienne-20261007.tar.zst.age présente sur Dedibackup ; etc/hostname restauré dans /tmp (sd-124443) |
| 4. Réseau OpenStack | Après redémarrage : SSH, dummy0, veth, Internet |
Redémarrage 11:37, SSH 11:39 ; interfaces et IP présentes ; ping 9.9.9.9 et DNS OK ; RAID [UU] |
| 5. Kolla | Services OK, aucune API joignable de l'extérieur | openstack service list et compute service list OK ; nmap sur tous les ports OpenStack + 1-1024 : 22 seul |
| 6. Console série | Invite affichée, commande exécutée | Script WebSocket : localhost login:, puis whoami && hostname → eleve, localhost |
| 7. Supervision | Une alerte de test reçue par Adam | Alerte injectée dans Alertmanager ; reçue par Adam sur ntfy |
| 8. Portail | Pest OK, élève fictif voit son tableau de bord | 11/11 tests ; lea.m connectée voit « Salut Léa » |
| 9. Console web | ip a dans le navigateur ; un autre élève refusé |
Sortie de ip a par navigateur → Nginx → proxy Go → Nova ; autre élève : 403 ; écriture du prof ignorée côté serveur |
| 10. Heat, lab 08 | Stack CREATE_COMPLETE, terminaux ouverts |
Stack créée en 26 s, 3 VM, topologie conforme au lab.yaml ; 3 terminaux ouverts ; expiration automatique vérifiée |
| 11. Stock et correction | < 5 s ; correct → réussi ; incorrect → échoué + message | 4,06 s (mesure pessimiste, voir étape 13) ; « Pas encore réussi » 6/10 avec les messages du lab, puis « Réussi » 10/10 ; 3 essais puis échec visible du prof, vérifiés |
| 12. HTTPS | Certificat valide, parcours prof → élève → lab → correction | Let's Encrypt, TLS 1.2/1.3, HSTS, CSP ; parcours en https/wss : 4,35 s, 6/10 puis 10/10 ; VM sans IP publique ni sortie |
| 13. Capacité et résistance | Chiffres écrits, restauration, retour seul après redémarrage | docs/capacite.md ; « RESTAURATION RÉUSSIE » (17 tables identiques) ; tout revenu seul en 11 min, parcours 10/10 ensuite ; ouverture mesurée à 2,80 / 2,85 / 2,85 s |
| 14. Légal et RGPD | Pages en ligne, purge prouvée par Pest | /legal, /confidentialite en 200, /statut → page de statut ; PurgeRgpdTest (5 tests) |
| 15. Visio | Prof + 2 élèves ; main levée → parole ; intrus refusé | Test Playwright à 3 navigateurs + intrus : « CRITÈRE DE L’ÉTAPE 15 : RÉUSSI » ; élève sans parole reste en sourdine ; intrus : « Authentication required » |
| 16. Nettoyage | Proposer le retrait de 90-adam |
Proposé avec ses conséquences ; Adam a choisi de le garder jusqu'à la fin du bloc A (voir risques) |
État relevé le 2026-10-12 à la fin de la mission : 0 unité systemd en
échec ; 53 conteneurs, 0 en mauvaise santé ; Nginx, PHP-FPM, Horizon, proxy
console, correcteur et relais d'alertes actifs ; https://syllabuslab.fr et
la page de statut en 200 ; certificat valable jusqu'au 2027-01-10 pour
syllabuslab.fr, www, status et meet ; une stack prête dans le stock
du lab 08 ; dernière sauvegarde le 2026-10-12 à 03:16, test de restauration
automatique du 2026-10-12 à 04:30 réussi ; 47 tests Pest et 4 tests Go.
Temps réel passé par étape
Pas de chronométrage pendant la mission : ce sont des fenêtres entre commits, pauses, attentes des réponses d'Adam et nuits comprises. Elles majorent le temps de travail réel.
| Étape | Fenêtre | Durée | Ce qui a pris du temps |
|---|---|---|---|
| 1 | 2026-10-07, jusqu'à 06:54 | — | Accès SSH (passphrase de la clé) |
| 2 | 06:54 → 10:32 | ≈ 3 h 40 | Deux retours arrière du filet anti-coupure, auto-bannissement fail2ban (post-mortem) |
| 3 | 10:32 → 11:08 | ≈ 35 min | Identifiants Dedibackup corrigés par Adam |
| 4 | 11:08 → 11:40 | ≈ 30 min | Redémarrage avec accord |
| 5 | 11:40 → 15:57 | ≈ 4 h 15 | Deux deploy (ProxySQL contre MariaDB), tables IPv6 de Docker |
| 6 | 15:57 → 16:24 | ≈ 30 min | — |
| 7 | 16:24 → 21:20 | ≈ 5 h | Attente de l'adresse de notification, configuration oubliée sur le serveur (2 fois) |
| 8 | 21:20 → 10-08 02:01 | ≈ 4 h 40 | Taille du portail, deux guards, déploiement |
| 9 | 02:01 → 09:35 | ≈ 7 h 30 (nuit comprise) | — |
| 10 | 09:35 → 10:14, puis ADR jusqu'à 21:01 | ≈ 40 min + questions | Trust Heat refusé aux application credentials (ADR 0002) |
| 11 | 10-08 → 21:52 | > 1 h 30 (journal) | Trois défauts des étapes 8 et 9 trouvés par le parcours réel |
| 12 | 10-09 09:38 → 15:04 | ≈ 1 h + DNS de status |
Faille XSS, /cours en 500 |
| 13 | 15:04 → 20:12 | ≈ 5 h | Test de capacité, sauvegarde du portail ajoutée, redémarrage |
| 14 | 20:12 → 22:18 | ≈ 2 h | Pages légales réécrites, polices auto-hébergées, retours d'Adam |
| 15 | 10-12 matin → 12:35 | une demi-journée | Pare-feu entre conteneurs (br_netfilter), rôles Jitsi |
| 16 et bilan | 10-12 après-midi | ≈ 1 h | — |
En tout : six jours calendaires, dont environ quatre jours de travail.
Capacité mesurée
- 20 VM
eleve.petit(1 vCPU, 768 Mo) en même temps, sessions et stock chaud compris : par exemple une classe de 20 élèves sur un lab à une VM, ou 6 élèves sur le lab 08 (3 VM chacun). Limite appliquée par Nova (reserved_host_memory_mb = 16500) et par le portail (LABS_CAPACITE_VM). - Pourquoi 20 : la mémoire est la limite (≈ 600 Mo par VM active, ≈ 250 Mo au repos), pas le CPU (20 vCPU à 100 % → hôte à 89 %, correction en 0,6 s). 22 avant la visio, 20 depuis qu'1,5 Go est réservé à Jitsi.
- Ouverture d'un lab pris dans le stock : 2,8 s (critère < 5 s). Lancement à froid de 20 VM : 53 s en médiane, 75 s au p95. D'où le pré-remplissage 10 minutes avant une séance.
- Visio : non mesurée au-delà de 3 participants. Une classe de 30 en visio est à tester au pilote (CPU de JVB, débit sortant).
Détails : docs/capacite.md.
Dettes et risques connus
La liste complète, tenue à jour, est dans docs/dette.md. Les risques qui
comptent avant une vraie classe :
| Risque | Conséquence | Réponse |
|---|---|---|
| Copie de la clé age non confirmée | Si le serveur est perdu, aucune sauvegarde n'est déchiffrable | Adam (voir plus bas) |
| Base OpenStack non sauvegardée | Perte du serveur → projet, compte, gabarits et stacks à recréer à la main | kolla-ansible mariadb_backup dans la sauvegarde quotidienne |
| Un seul serveur, pas de sonde extérieure | Si le serveur tombe, aucune alerte, et la classe s'arrête | Sonde externe (à décider et commander par Adam) ; self-healing ne couvre pas la panne totale |
| Visio sans TURN sur 443 | Sur un réseau scolaire qui bloque l'UDP : ni son ni image | coturn derrière 443 avant le pilote |
sudo sans mot de passe pour adam |
La clé SSH de Claude Code donne un accès root complet | Gardé par choix d'Adam jusqu'à la fin du bloc A ; retrait ensuite (commande prête ci-dessous) |
| Images Kuma non figée, Jitsi sans procédure de mise à jour | Mise à jour non testée au prochain redéploiement | Variables de version dans les rôles |
| Vitrine : Tailwind par CDN, scripts en ligne, Pyodide depuis jsDelivr | CSP de la vitrine moins stricte que celle de l'application | Compilation par Vite avant ouverture publique |
| Peu de vérifications dans un vrai navigateur | Hors visio et /ide, les pages n'ont été vérifiées qu'en HTML |
Playwright est maintenant installé : l'étendre aux parcours clés |
| Kolla installé depuis une branche | Pas reproductible à l'identique | À régler lors de la montée de version |
Deux incidents de ma part, déjà traités : un secret d'application credential
de test affiché en clair (credential supprimée aussitôt) ; un déploiement en
échec pris pour un succès (règle depuis : toujours lire PLAY RECAP).
Ce qu'Adam doit faire lui-même
Secrets et sécurité
- Copier la clé age hors du serveur et le prouver : procédure dans
docs/runbooks/sauvegardes.md(déchiffrer~/Desktop/test-cle-sauvegardes.ageavec la copie). Ranger ensuite la copie dans un gestionnaire de mots de passe. - Changer la passphrase SSH si l'ancienne clé ou la même passphrase sert ailleurs : elle avait été collée dans la conversation à l'étape 1.
- Retirer
/etc/sudoers.d/90-adamà la fin du bloc A (la clé de Claude Code n'a pas de passphrase : ce fichier est la seule barrière entre elle et root). D'abord vérifier son mot de passe dans sa propre session (sudo -k && sudo -v), garder cette session ouverte, puis :sudo rm /etc/sudoers.d/90-adam. Les playbooks se lancent ensuite avec-K. - Faire tourner le mot de passe du compte
paillasse-serviceune fois par an (docs/runbooks/compte-service-openstack.md).
Comptes et contenus
- Créer le premier vrai compte prof (le sien) sur
https://syllabuslab.fr/inscriptionet une vraie classe. - Compléter les CGU (article « Disponibilité et responsabilité ») et indiquer un DPO s'il en désigne un.
- Trancher les slogans « du lycée au master » et le sort des 32 pages d'aperçu.
- Dire si l'ancien
storage/logs/laravel.logpeut être supprimé.
Tests avec un prof
- Faire jouer une séance complète par un collègue prof, sur un vrai réseau d'établissement : inscription des élèves (fiches et code de classe), séance planifiée, lab 08, correction, visio (son et image à travers le filtrage de l'établissement, c'est là que l'absence de TURN se verra), archivage de la classe.
- Vérifier dans son navigateur :
/ide(Python et SQL), une console de lab, la visio sur Chromebook ou vieux PC.
Décisions et achats (jamais par Claude)
- Sonde de supervision hors du serveur (petite VM ailleurs, ou service
externe) et nom DNS
turn.syllabuslab.frpour la visio.
Prochaines étapes du bloc A
1. Self-healing et post-mortem (semaine 6 du CLAUDE.md)
- Détecter et relancer : VM figée (l'agent invité ne répond plus →
nova reboot --hard), stack du stock en erreur (supprimée et recréée : déjà en partie fait par le ménage du stock), service arrêté (Restart=on-failuresur toutes les unités maison, à vérifier une par une), conteneur Kolla arrêté. - Une panne provoquée par cas (
kill -STOPdu QEMU d'une VM du stock, arrêt du correcteur, arrêt denova_compute), réparée sans intervention, chacune suivie d'un post-mortem dansdocs/postmortems/. - Avant : sauvegarde de la base OpenStack, sinon une réparation ratée n'a pas de filet.
2. Montée de version d'OpenStack (semaine 7)
- Passer de la branche
stable/2025.2à un tag (version figée), puis préparer la série suivante. Attention : 2026.1 ne supporte plus Debian 12. Une montée de version d'OpenStack passe donc d'abord par Debian 13 (montée de version de l'OS sur un serveur unique, à préparer avec le mode rescue). - Runbook : sauvegarde des bases,
kolla-ansible upgradeen service systemd, vérifications (capacite.pyréduit,parcours-lab.py,visio-e2e.mjs), retour arrière. Retour d'expérience dans le journal.
3. Pilote avec une vraie classe (semaine 8)
- Prérequis : TURN 443, base OpenStack sauvegardée, clé age confirmée, sonde extérieure, mentions légales complètes, test avec un collègue (point 9).
- Pendant : relever le temps d'ouverture réel (p95), la mémoire, la charge de la visio, les corrections réussies et échouées, les mains levées.
- Après : retours des élèves et du prof, métriques dans
docs/capacite.md, liste des priorités du bloc B.