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.
Commit `.hoody/crontab` dans le repo, à côté de vos jobs. Quand le script de déploiement lance un conteneur pour `main`, `feature/billing-v2` ou n'importe quelle branche de preview, il PUT ce fichier sur la Cron API du nouveau container. La planification voyage avec la branche — et disparaît quand la branche disparaît.
un fichier par branche · même chemin dans chaque repo · pas de serveur cron partagé
Chaque conteneur de branche fait tourner Hoody Cron. Le script de déploiement lit le crontab committé et le PUT sur l'endpoint raw-crontab du nouveau container. Le conteneur exécute la planification décrite par le fichier — ni plus, ni moins.
#!/bin/sh
# Provisionne un conteneur neuf pour cette branche.
BRANCH=$(git branch --show-current)
CTR=$(hoody containers create --from main-snapshot)
# Remplace le crontab du conteneur par celui du repo.
curl -X PUT --data-binary @.hoody/crontab \
-H "Content-Type: text/plain" \
https://$CTR-cron-1.hoody.com/users/root/crontab
# Terminé. La planification de la branche vit dans son container.
echo "deployed $BRANCH → $CTR"# Endpoint raw-crontab Hoody Cron — remplace tout le fichier 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, planification active 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 la planification devenue un fichier dans le repo, trois catégories de travail disparaissent.
Quand vous passez `billing-rollup.sh` en v2, la nouvelle planification arrive dans la même pull request. Le reviewer voit la ligne cron juste à côté du script. Reverte un commit et la planification revient avec lui.
Les conteneurs de branche sont éphémères. Quand vous mergez ou fermez la branche, vous démontez le container. Le crontab vivait dedans, donc la planification disparaît sans concierge — aucun serveur cron partagé ne garde d'entrées obsolètes.
Un job expérimental horaire sur `experiment/llm-rollups` tourne dans son propre conteneur avec son propre filesystem. Le démon cron de staging ne le voit jamais ; celui de production non plus. Pas de garde `if BRANCH_ENV` à l'intérieur des jobs.
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 feature — c'est l'endroit où vit la planification. Un fichier que la branche transporte, ou 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 Cron API, pas de benchmarks inventés.
Chaque conteneur de branche a son propre crontab par utilisateur. PUT le fichier complet, GET en retour, remplace-le de manière atomique. Pas de table de planification partagée derrière.
Crontab brut (GET/PUT), entrées gérées (POST/PATCH/DELETE avec UUID et `expires_at`), et listing par utilisateur. Choisis ce dont votre script de déploiement a besoin.
Standard `min hour day month dow` plus macros : `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`. La même syntaxe que votre `.hoody/crontab` utilise déjà.
D'après la Hoody Cron API : GET/PUT /users/[user]/crontab et POST/PATCH/DELETE /users/[user]/entries sur l'URL du service cron de chaque container.
La planification vit à côté du code qui tourne dessus, dans le même conteneur, sur la même branche.
Six endroits où vivait la planification cron, aucun à côté du code. Le crontab lié à la branche les rend tous redondants.
Arrêtez de synchroniser des planifications entre systèmes. Commitez le crontab. Laissez la branche le porter.