Soixante conteneurs sur un seul serveur
Une seule machine bare-metal fait tourner des dizaines à des centaines de conteneurs Hoody. La déduplication KSM et BTRFS rend le coût marginal quasi nul.
votre CI matrix fan-out sur trente test runners. Chacun a besoin de la même image de 800 MB. Stream le tarball dans un chemin pipe avec ?n=30. Les trente workers curl la même URL. Les octets passent une fois, le serveur ne tient rien, et aucun credential de registry n'est rotaté.
# stream l'image une foistar c ./image.tar | curl -T - https://pipe.hoody.com/build-12af?n=30UN ENVOYEUR À GAUCHE. TRENTE RÉCEPTEURS GET À DROITE. LE PIPE ATTEND QUE TOUT LE MONDE ÉCOUTE, PUIS LES OCTETS PASSENT UNE FOIS.
Le pipe est un routeur fan-out sans disque. Le POST de l'envoyeur sur /api/v1/pipe/[path]?n=30 bloque jusqu'à ce que trente récepteurs se connectent à la même URL avec le même n. Puis les octets coulent du conteneur build directement à travers chaque runner, simultanément, à la vitesse du récepteur le plus lent.
tar c | curl -T - https://pipe/.../build?n=30Le conteneur build pipe le tarball direct dans curl. Pas de fichier écrit, pas de registry pushé.
POST /api/v1/pipe/[path]?n=30Le serveur tient l'envoyeur jusqu'à ce que les trente récepteurs se connectent. Un n incohérent renvoie 400. Les récepteurs pré-connectés sont OK.
curl https://pipe/.../build?n=30 | tar xChaque runner reçoit des octets identiques. La backpressure flue depuis le récepteur le plus lent, pas depuis la bande passante de l'envoyeur.
Rien ne persiste. Rien n'est mis en cache. Le pipe brokere la connexion, puis se met de côté. Quand le runner le plus lent finit, le transfert finit — et l'URL disparaît.
Naïf : trente pulls registry du même tarball de 800 MB, trente caches froids, trente aller-retour réseau. Pipe : un egress, un transfert, le récepteur le plus lent donne le rythme.
12s
Un egress à pleine vitesse. Le récepteur le plus lent donne le rythme, mais personne ne re-télécharge.
1× / build
Les octets quittent le builder une fois, fan-out au pipe. Pas de frais GET S3, pas de pulls Docker Hub.
0 octet
Le pipe ne tient rien sur disque. Pas de registry à nettoyer, pas de clé de cache à invalider.
Le chiffre du temps wall suppose une matrix de 30 sur le même réseau régional que le conteneur build ; les transferts cross-region sont limités par la bande passante inter-région, pas par le pipe.
Une fois que le build est une URL et trente curls, une pile de scaffolding CI disparaît. Pas de stockage d'artefacts à faire vieillir. Pas de credentials de registry à rotater. Pas de cache action à debugger.
La backpressure est intégrée au pipe. Les workers rapides ne perdent pas un aller-retour registry à attendre le lent — ils attendent au pipe, puis boivent au même rythme. Personne ne re-télécharge.
Rien n'est pushé vers un registry, donc rien n'a besoin de s'authentifier. L'URL elle-même est le credential — courte durée, scoped à un transfert, évincée quand le build finit.
Les octets quittent le builder une fois. Le pipe diffuse. vous payez un egress par build au lieu de trente pulls registry par run de matrix.
Le pipe est par-build, pas par-clé. Pas de cache GitHub Actions à mal-hit, pas de mystère de couches buildx, pas de tarball obsolète de la main de la semaine dernière.
Le même pattern gère node_modules, .pnpm-store, target/, le cache des wheels, le shard de dataset. Si ça stream, ça fan-out.
Un envoyeur. Trente récepteurs. Zéro facture S3.
Un push 30 voies qui auparavant s'étranglait sur un aller-retour S3 circule maintenant par un seul tube et une seule sortie. Personne n'est obligé de re-télécharger. Aucune rotation de credentials de registry. L'URL s'efface d'elle-même à la fin de la matrice.
Les pièces qu'un flux matrix-CI doit normalement assembler — registry, cache action, miroir, étape d'upload maison. Le pipe les plie en une URL.
Arrêtez de pusher le même tarball trente fois. Pushez-le une fois. Laissez trente curls partager le stream.