Zum Inhalt springen
use-cases / crontab-per-branch / hero
CRON · GIT · ZEITPLÄNE PRO BRANCH

Eine crontab pro Branch, mit dem Code deployt

Checke `.hoody/crontab` ins Repo neben deine Jobs ein. Wenn das Deploy-Skript einen Container für `main`, `feature/billing-v2` oder einen beliebigen Preview-Branch hochfährt, PUTet es diese Datei an die Cron-API des neuen Containers. Der Zeitplan reist mit dem Branch — und verschwindet, wenn der Branch verschwindet.

Cron-API lesen
use-cases / crontab-per-branch / mechanism

Wie aus `.hoody/crontab` ein echter Zeitplan wird

Jeder Branch-Container betreibt Hoody Cron. Das Deploy-Skript liest die eingecheckte crontab und PUTet sie an den Raw-crontab-Endpoint des neuen Containers. Der Container fährt den Zeitplan, den die Datei beschreibt — nicht mehr, nicht weniger.

deploy.sh · von CI gepusht
shell · client
#!/bin/sh
# Provisioniere einen frischen Container für diesen Branch.
BRANCH=$(git branch --show-current)
CTR=$(hoody containers create --from main-snapshot)

# Ersetze die crontab des Containers durch die aus dem Repo.
curl -X PUT --data-binary @.hoody/crontab \
  -H "Content-Type: text/plain" \
  https://$CTR-cron-1.hoody.com/users/root/crontab

# Fertig. Der Zeitplan des Branches lebt in seinem Container.
echo "deployed $BRANCH → $CTR"
PUT /users/root/crontab
cron · server
# Hoody Cron Raw-crontab-Endpoint — ersetzt die ganze Datei atomar.
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: Cron-Daemon lädt neu, Zeitplan in unter einer Sekunde aktiv.

Die crontab sind Daten, die der Branch ausliefert, nicht State, den der Cron-Server sich merkt. Lösche den Container, und es bleibt kein Eintrag zum Aufräumen — die Datei ging mit der Disk.

use-cases / crontab-per-branch / powers

Drei Dinge, die du nicht mehr tust

Sobald der Zeitplan eine Datei im Repo ist, verschwinden drei Arten von Arbeit.

VERSIONIERUNG

Zeitpläne reisen im selben Diff wie der Code

Wenn du `billing-rollup.sh` auf v2 änderst, landet der neue Zeitplan im selben Pull Request. Der Reviewer sieht die Cron-Zeile direkt neben dem Skript. Revert einen Commit, und der Zeitplan kehrt mit zurück.

TEARDOWN

Lösche den Branch, der Cron geht mit

Branch-Container sind ephemer. Wenn du den Branch mergst oder schließt, fährst du den Container ab. Die crontab lebte in ihm, also verschwindet der Zeitplan ohne Janitor — kein gemeinsamer Cron-Server hält veraltete Einträge.

ISOLATION

Das Experiment kann nicht in Staging feuern

Ein stündlicher Experimentaljob auf `experiment/llm-rollups` läuft in seinem eigenen Container mit eigenem Dateisystem. Stagings Cron-Daemon sieht ihn nie; Productions Cron-Daemon sieht ihn nie. Es gibt keine `if BRANCH_ENV`-Wachen in den Jobs selbst.

use-cases / crontab-per-branch / compare

Geteilte crontab vs. Branch-crontab

Das Standardmodell „eine ops-verwaltete crontab" und das Branch-gebundene Modell scheitern in entgegengesetzte Richtungen. Gleicher Job, sehr unterschiedlicher Blast Radius.

ACHSEGETEILTE CRONTABBRANCH-CRONTAB
Source of Truth
ops-Wiki + Ansible-RolleZeitplan lebt in einem anderen Repo als das Skript
.hoody/crontab im Reponeben dem Skript, das die Cron-Zeile aufruft
Einen Job hinzufügen
Code mergen → Ops anpingen → SSH zum Cron-Hostzwei Systeme müssen sich manuell einig sein
Datei editieren, pushen, deployenein Diff, ein Merge, ein Deploy
Branch-Isolation
if [ "$ENV" = staging ]; then …jeder Job kennt jede Umgebung
Container pro Branchkein Env-Flag im Skript
Aufräumen
daran denken, die Zeile zu entfernenveraltete Einträge stapeln sich über Jahre
Branch gelöscht = Cron gelöschtDateisystem weg, Zeitplan weg
Experimente
die Production-crontab ist die einzigejeder Test riskiert, in Prod zu feuern
Spike-Branch = Spike-crontabfeuert nur in seinem Container

Der Unterschied ist kein Feature — es ist, wo der Zeitplan lebt. Eine Datei, die der Branch trägt, vs. eine Zeile in einer geteilten Tabelle, von der sich der Branch borgt.

use-cases / crontab-per-branch / capacity

Was Hoody Cron dir tatsächlich gibt

Per-Container-Cron ist eine echte REST-Oberfläche — drei Endpoint-Familien, Standard-Cron-Syntax, volle Per-User-Isolation. Zahlen aus der Cron-API-Spec, keine erfundenen Benchmarks.

  1. CRONTAB PRO CONTAINER1

    Jeder Branch-Container hat seine eigene Per-User-crontab. PUTe die ganze Datei, GETe sie zurück, ersetze sie atomar. Keine geteilte Schedule-Tabelle im Hintergrund.

  2. ENDPOINT-FAMILIEN3

    Raw-crontab (GET/PUT), verwaltete Einträge (POST/PATCH/DELETE mit UUIDs und `expires_at`) und Per-User-Listing. Pick, was dein Deploy-Skript braucht.

  3. FELD-CRON-AUSDRÜCKE5

    Standard `min hour day month dow` plus Makros: `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`. Gleiche Syntax, die deine `.hoody/crontab` schon nutzt.

Laut Hoody Cron API: GET/PUT /users/[user]/crontab und POST/PATCH/DELETE /users/[user]/entries an der Cron-Service-URL jedes Containers.

use-cases / crontab-per-branch / punchline

Der Zeitplan lebt neben dem Code, der auf ihm läuft, im selben Container, auf demselben Branch.

vorher · zwei Systeme zu merkennachher · eine Datei im Repo
WAS DU FRÜHER HATTESTSchedule in ops/ansible · Code in app/ · sie waren sich nie einigPR mergen, dann Ticket aufmachen, um den Cron-Host zu aktualisieren
WAS DU JETZT HASTPUT @.hoody/crontab → cron-1.[branch].hoody.comein PUT, ein Container, ein Zeitplan, ein Branch
Cron-API lesen
use-cases / crontab-per-branch / replaces

Was das ersetzt

Sechs Orte, an denen der Cron-Zeitplan früher lebte, keiner davon neben dem Code. Die Branch-gebundene crontab macht sie alle überflüssig.

  • geteilte Production-crontabEine Datei auf einem Cron-Host, um die jedes Team koordinieren musste
  • manuelle Cron-Config-SynchronisationAnsible-Rolle / Puppet-Manifest, das außerhalb deiner Code-Merges angewendet wird
  • GitHub-Actions-Schedules an main gebundenZeitpläne an den Default-Branch gebunden, unsichtbar für Feature-Arbeit und Previews
  • „daran denken, Cron beim Mergen zu aktualisieren"Ein menschlicher Checklisten-Eintrag — das einzige, was zwischen dir und einem veralteten Eintrag steht
  • separates Cron-Config-RepoEin zweites Repo, dessen einziger Job es war, hinter dem mit dem echten Code herzuhinken
  • Atlas/Liquibase-Scheduled-MigrationsMigrationstools, die Schedule-Dienst leisten, weil es nirgendwo besser für ihn gab
use-cases / crontab-per-branch / cta

Hör auf, Zeitpläne über Systeme hinweg zu synchronisieren. Checke die crontab ein. Lass den Branch sie tragen.

Cron-Docs lesen
use-cases / crontab-per-branch / related

Lies die anderen