
Soixante conteneurs sur un seul serveur
Une machine bare-metal exécute des dizaines à des centaines de conteneurs Hoody. La dédupplication KSM et BTRFS rend le coût marginal quasi nul.
Hoody Cron porte la planification. Hoody Exec porte la logique de renouvellement. Dimanche à 04:00, un curl se déclenche, certbot tourne, le nouveau bundle est PATCHé dans le proxy, et le reload est acquitté. Aucune session shell, aucune clé dans ~/.ssh, aucun jump host entre vous et le certificat.
# weekly · Sunday 04:00 0 4 * * 0 bash /scripts/renew.shhebdomadaire · POSTée une fois · auto-exécutée pour toujours
pas de clé SSH · pas de jump host · la planification est une ligne dans une API JSON
Tout le pipeline de renouvellement, ce sont deux endpoints et une planification à 5 champs. Cron déclenche Exec. Exec appelle ACME et envoie un PATCH au proxy. L'accusé de réception revient sous forme de 200.
POST /users/me/entries avec schedule "0 4 * * 0" et command "curl /scripts/certs/renew". Le service cron l'écrit dans la crontab utilisateur et commence à tourner. Vous l'avez fait une seule fois, depuis n'importe où en HTTPS.
Dimanche 04:00, cron curl l'URL exec. Exec démarre le script, parle au endpoint ACME de Let's Encrypt, valide le challenge http-01, et écrit le bundle renouvelé dans /files. Aucun nœud connecté, aucune session nécessaire.
Le script PATCHe le nouveau certificat et la nouvelle clé dans l'endpoint bundle du proxy Hoody. Le proxy se recharge à chaud — pas de redémarrage — et le prochain handshake TLS sert le nouveau certificat. Tout le cycle est en moins d'une minute.
Chaque étape est un appel HTTP que vous pouvez rejouer depuis un terminal — `curl --dry-run` si vous voulez déboguer, `curl -i` si vous voulez les en-têtes. Le pipeline ne dépend d'aucune session connectée à aucun moment.
À gauche, l'entrée cron qui planifie le job. À droite, le script exec qui fait le travail. Les deux sont adressables via HTTP — les deux sont auditables, les deux sont rejouables depuis n'importe quel ordinateur portable ou téléphone.
# register the weekly renewal curl -X POST \ https://cron.containers.hoody.com/users/me/entries \ -H "Content-Type: application/json" \ -d '[ "schedule":"0 4 * * 0", "command":"curl -fsS https://exec.containers.hoody.com/scripts/certs/renew", "comment":"weekly TLS renewal", "enabled":true ]' # response HTTP/1.1 201 Created { "id":"7a92", "schedule":"0 4 * * 0", "enabled":true }
// scripts/certs/renew.ts // @mode serverless // @timeout 120000 const domains = ["your-app.com", "api.your-app.com", ...]; for (const d of domains) { const cert = await acme.order(d); await fetch("/api/v1/proxy/cert/bundle", { method: "PATCH", body: JSON.stringify({ d, cert }) }); } return { "renewed": domains.length };
Deux URLs, un dimanche matin, zéro SSH. L'entrée cron est de la donnée — POSTez-la une fois et elle est là jusqu'à ce que vous fassiez DELETE. Le script exec est un fichier — modifiez-le via l'API et la prochaine exécution prend la nouvelle logique. Rien dans cette boucle n'exige qu'une personne soit sur une machine.
Même résultat — un certificat renouvelé chaque semaine — avec trois propriétés que la configuration historique n'a jamais eues.
L'auth est un token URL, pas une clé SSH. Faites-la tourner via l'API et l'ancien token cesse de fonctionner partout d'un coup. Pas d'agent forwarding, pas de bastion, pas de fichier de clé dont vous avez oublié que vous l'aviez copié sur une machine de CI il y a trois ans.
Chaque exécution est une ligne dans le log cron et une ligne de requête dans le log exec. Grep pour savoir qui l'a déclenchée, quand, quel cert, quel code de réponse. Le 200 du proxy est l'accusé de réception confirmant que le reload est passé.
Rejouez le renouvellement depuis votre ordinateur portable avec `curl /scripts/certs/renew?dry_run=true`. Regardez la réponse, corrigez le script via l'API write d'exec, réessayez. Toute la boucle se passe en HTTPS — le même tuyau que celui qu'utilise la planification de production.
Des chiffres issus du déploiement, pas de benchmarks. C'est la forme qui compte : très peu de pièces mobiles, toutes parlent HTTP.
L'installation est un POST. Le renouvellement est un GET planifié. Le debug est un curl. Il n'y a aucune session shell dans le pipeline, à aucun moment — votre clé privée n'a jamais à être sur la machine.
Une entrée cron pour planifier l'exécution. Une route exec qui lance le script. La troisième URL — le PATCH du bundle proxy — vit à l'intérieur du script et recharge le certificat.
Expression standard à 5 champs "0 4 * * 0" — dimanche 04:00. Ou `@weekly` si vous ne tenez pas au jour précis. Le service cron accepte les deux, plus l'auto-expiration pour les renouvellements one-shot.
Service cron : expressions à 5 champs et macros (`@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`), isolation par utilisateur, `expires_at` optionnel. Exec : V8 isolates, runtime Bun, magic comments pour mode/timeout/CORS. Le flux ACME est géré dans votre script — Hoody n'exécute pas certbot pour vous, il exécute votre code à intervalle régulier.
Le renouvellement est un curl planifié — pas de session shell, pas de clé, pas de jump host.
Les manières standards de garder TLS valide en production. Chacune veut soit une session shell, soit un service de control plane, soit les deux. Le duo cron-plus-exec ne veut ni l'un ni l'autre.
Arrêtez de vous connecter pour renouveler vos certs. POSTez la planification une seule fois. Regardez le proxy se recharger tout seul chaque dimanche matin.