
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.
Versionnez `.hoody/crontab` dans le dépôt à côté de vos jobs. Lorsque le script de déploiement crée un conteneur pour `main`, `feature/billing-v2` ou n'importe quelle branche de prévisualisation, il envoie ce fichier en PUT sur l'API Cron du nouveau conteneur. Le planning embarque avec la branche — et disparaît quand la branche disparaît.
un fichier par branche · même chemin dans chaque dépôt · pas de serveur cron partagé
Chaque conteneur de branche exécute Hoody Cron. Le script de déploiement lit le crontab versionné et l'envoie en PUT sur l'endpoint raw-crontab du nouveau conteneur. Le conteneur exécute le planning décrit par le fichier — ni plus, ni moins.
#!/bin/sh
# Provisionner un conteneur neuf pour cette branche.
BRANCH=$(git branch --show-current)
CTR=$(hoody containers create --from main-snapshot)
# Remplacer le crontab du conteneur par celui du dépôt.
curl -X PUT --data-binary @.hoody/crontab \
-H "Content-Type: text/plain" \
https://$CTR-cron-1.hoody.com/users/root/crontab
# Terminé. Le planning de la branche vit dans son conteneur.
echo "deployed $BRANCH → $CTR"# Endpoint raw-crontab de Hoody Cron — remplace le fichier entier de manière atomique.
PUT /users/root/crontab HTTP/1.1
Host: ctr_4d72b9-cron-1.hoody.com
Content-Type: text/plain
0 2 * * * /srv/jobs/billing-rollup-v2.sh
*/15 * * * * /srv/jobs/sync-stripe.py
@hourly curl -fsS http://localhost/healthz
*/5 * * * * /srv/jobs/diff-v1-v2.sh
HTTP/1.1 200 OK
# 200 OK : le démon cron recharge, planning actif en moins d'une seconde.Le crontab est une donnée que la branche transporte, pas un état que le serveur cron mémorise. Supprimez le conteneur, et il ne reste aucune entrée à nettoyer — le fichier est parti avec le disque.
Une fois que le planning est un fichier dans le dépôt, trois catégories de travail disparaissent.
Quand vous changez `billing-rollup.sh` en v2, le nouveau planning arrive dans la même pull request. Le relecteur voit la ligne cron juste à côté du script. Annulez un commit et le planning est annulé avec lui.
Les conteneurs de branche sont éphémères. Quand vous fusionnez ou fermez la branche, vous démontez le conteneur. Le crontab vivait dedans, donc le planning disparaît sans concierge — il n'y a pas de serveur cron partagé qui retient des entrées obsolètes.
Un job expérimental horaire sur `experiment/llm-rollups` tourne dans son propre conteneur avec son propre système de fichiers. Le démon cron de staging ne le voit jamais ; le démon cron de production ne le voit jamais. Il n'y a pas de garde-fous `if BRANCH_ENV` à l'intérieur des jobs eux-mêmes.
Le modèle standard "un crontab géré par les ops" et le modèle lié à la branche échouent dans des directions opposées. Même job, rayon d'impact très différent.
La différence n'est pas une fonctionnalité — c'est l'endroit où vit le planning. Un fichier que la branche transporte, vs une ligne dans une table partagée que la branche emprunte.
Le Cron par conteneur est une vraie surface REST — trois familles d'endpoints, syntaxe cron standard, isolation totale par utilisateur. Chiffres tirés de la spec de l'API Cron, pas de benchmarks inventés.
Chaque conteneur de branche a son propre crontab par utilisateur. PUT du fichier complet, GET pour le récupérer, remplacement atomique. Aucune table de planning partagée en coulisses.
Crontab brut (GET/PUT), entrées gérées (POST/PATCH/DELETE avec UUID et `expires_at`), et listage par utilisateur. Choisissez ce dont votre script de déploiement a besoin.
Standard `min hour day month dow` plus les macros : `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`. La même syntaxe que celle que votre `.hoody/crontab` utilise déjà.
Selon l'API Hoody Cron : GET/PUT /users/[user]/crontab et POST/PATCH/DELETE /users/[user]/entries sur l'URL du service cron de chaque conteneur.
Le planning vit à côté du code qu'il déclenche, dans le même conteneur, sur la même branche.
Six endroits où le planning cron vivait, aucun à côté du code. Le crontab lié à la branche les rend tous redondants.
Arrêtez de synchroniser des plannings entre systèmes. Versionnez le crontab. Laissez la branche le porter.