FrameForge est un projet pédagogique autonome : une plateforme interne d’encodage vidéo batch, orchestrée et résiliente. Il constitue le PoC du bloc 5 « Concevoir et mettre en œuvre l’architecture d’un SI ».
Le cas est fictif. Le dépôt ne contient ni code d’entreprise, ni donnée métier réelle, ni vidéo utilisateur. Les médias de démonstration sont générés synthétiquement.
Le code applicatif, le déploiement reproductible et la recette automatisée sont fournis. Il s’agit néanmoins d’un PoC de laboratoire, pas d’un service prêt pour la production. Les commandes d’acceptation ci-dessous produisent des preuves locales ; leur seule source de vérité reste le rapport de test. Ce README ne présume jamais qu’une campagne non exécutée a réussi.
- dépôt multipart direct dans un stockage compatible S3 ;
- mise en file durable avec RabbitMQ et publication transactionnelle par outbox ;
- création de Jobs Kubernetes éphémères par KEDA, de zéro à deux workers ;
- encodage FFmpeg H.264/AAC en 720p et génération d’une vignette ;
- livraison au moins une fois, reprise après interruption et sorties déterministes ;
- suivi des états dans PostgreSQL et supervision Prometheus/Grafana ;
- déploiement et destruction bornés à un cluster et un répertoire nommés.
flowchart LR
B[Navigateur] --> UI[UI React]
B --> API[API Fastify]
B -- parties signées --> S3[Garage / API S3]
API --> PG[(PostgreSQL)]
API --> S3
API -- outbox --> MQ[(RabbitMQ)]
MQ -. profondeur de file .-> KEDA[KEDA ScaledJob]
KEDA -- crée 0 à 2 Jobs --> W[Worker FFmpeg]
MQ -- jobId consommé puis acquitté --> W
W --> PG
W -- source et rendus --> S3
PROM[Prometheus] --> API
PROM --> MQ
PROM --> KEDA
GRAF[Grafana] --> PROM
Le PoC crée un cluster k3d nommé frameforge, composé d’un serveur K3s et
d’un agent sur le même hôte physique. Le namespace applicatif porte également
le nom frameforge. Les données persistantes du laboratoire sont exclusivement
placées sous /srv/frameforge.
Environnement attendu : Linux amd64 ou arm64, avec accès réseau sortant pour
télécharger les outils et les images.
- Docker fonctionnel pour l’utilisateur courant ;
- Bash,
curl,tar,sha256sum, OpenSSL,ripgrepetsudo; - une IPv4 privée assignée à une interface de l’hôte ;
- les ports
8088(Ingress) et6550(API Kubernetes sur loopback) libres ; - pour la recette complète : Node.js 22+, npm et
jq.
Enveloppe minimale recommandée pour jouer toute la recette, y compris deux
encodages simultanés : 8 processeurs logiques, 16 Gio de mémoire et 100 Gio de
disque libre. Une marge supplémentaire est préférable pour
make acceptance-large.
Les versions de k3d, K3s, kubectl, Helm, KEDA et des services sont centralisées
dans deploy/versions.env. Les binaires téléchargés par
le projet sont contrôlés par somme SHA-256.
Depuis la racine du dépôt, saisir une IPv4 privée réellement assignée au serveur :
read -r -p "IPv4 privée du serveur : " HOST_IP
export HOST_IP
make pocLa commande télécharge les outils épinglés, crée le cluster, construit les trois images applicatives, déploie KEDA et le chart Helm, puis exécute les vérifications structurelles et les sondes HTTP. Le port est configurable sans modifier le dépôt :
POC_PORT=8088 make pocSi Tailscale est installé, son IPv4 peut être fournie explicitement. HOST_IP
doit dans tous les cas appartenir à une interface locale ; les adresses wildcard,
loopback ou broadcast sont refusées.
Avec le port par défaut, remplacer <IP> dans les adresses suivantes :
| Service | Adresse |
|---|---|
| Interface FrameForge | http://ui.<IP>.nip.io:8088 |
| API | http://api.<IP>.nip.io:8088 |
| Stockage S3 | http://s3.<IP>.nip.io:8088 |
| Grafana | http://grafana.<IP>.nip.io:8088 |
| RabbitMQ Management | http://rabbit.<IP>.nip.io:8088 |
Les secrets d’exécution sont générés au déploiement et stockés dans des Secrets
Kubernetes. Ils ne doivent jamais être recopiés dans le dépôt ou dans une preuve
publique. L’API Kubernetes du cluster reste liée à 127.0.0.1:6550.
Le bouton Lancer 20 jobs de l'interface charge une seule mire vidéo intégrée
de 30 secondes, puis l'envoie sous les noms video-01.mp4 à video-20.mp4. Le
navigateur borne les uploads à trois en parallèle et KEDA conserve son plafond
de deux workers. Les liens RabbitMQ et Grafana placés à côté du bouton permettent
d'observer la file, les Jobs et les ressources des pods pendant la démonstration.
Ce lanceur facilite une démonstration manuelle ; il ne remplace pas les scénarios
de recette mesurés par make acceptance.
Contrôles locaux applicatifs et statiques :
npm ci
npm run typecheck
npm test
make lintAprès make poc, la recette nominale vérifie notamment le plafond de deux
workers, les sorties H.264 720p, la reprise après suppression forcée d’un pod en
moins de 60 secondes, la DLQ et l’idempotence :
make acceptanceLa variante suivante ajoute une vidéo synthétique comprise entre 1 000 000 000 octets et 1 Gio, et peut durer jusqu’à trente minutes :
make acceptance-largeLes preuves horodatées et leurs empreintes sont écrites dans
evidence/runtime/, volontairement ignoré par Git. Pour une collecte seule :
make evidenceLe sous-ensemble assaini de la campagne finale est versionné dans evidence/public/FF-RECETTE-001. Il contient les résumés, les contrôles R8, la preuve de nettoyage et les empreintes de rattachement aux preuves privées, sans journal ni identifiant d'environnement.
make destroy-pocCette commande collecte d’abord les preuves disponibles, supprime uniquement le
cluster k3d nommé frameforge, puis met en quarantaine et efface définitivement
/srv/frameforge. Les bases, objets et fichiers de travail supprimés ne sont
pas récupérables.
Le script refuse d’agir si le nom du cluster, le chemin, la sentinelle du projet
ou l’inventaire préalable ne correspondent pas exactement aux valeurs attendues.
Il ne lance ni docker system prune, ni suppression globale de clusters. Le
checkout Git, evidence/runtime/ et les images présentes dans le cache Docker de
l’hôte ne sont pas supprimés.
- toutes les briques s’exécutent sur un seul hôte : le PoC n’est pas hautement disponible ;
- PostgreSQL, RabbitMQ et Garage n’ont chacun qu’une instance ; une file quorum mono-nœud ne protège pas contre la perte de l’hôte ;
- l’UI et l’API applicative n’implémentent pas d’authentification ;
- les flux exposés utilisent HTTP, sans TLS de bout en bout ni mTLS interne ;
- il n’existe ni chiffrement au repos, ni sauvegarde hors site, ni procédure de restauration automatisée ;
- les noms
nip.ioet le réseau privé servent uniquement à la démonstration ; - les politiques réseau et les conteneurs non-root réduisent le risque, sans transformer ce laboratoire en architecture de production.
N’exposez pas ce PoC directement sur Internet. Consultez la politique de sécurité avant tout déploiement.
- Dossier complet du bloc 5
- Support de soutenance Marp
- Support de soutenance PDF
- Support de soutenance PowerPoint
- Preuves publiques FF-RECETTE-001
- ADR 0001 — périmètre et plateforme
- ADR 0002 — sémantique des travaux
- ADR 0003 — isolation et capacité
- Composants et licences tierces
Le code et la documentation propres à FrameForge sont distribués sous licence MIT. Les composants tiers conservent leurs licences respectives.