
Sechzig Container auf einem Server
Eine Bare-Metal-Box führt Dutzende bis Hunderte von Hoody-Containern aus. KSM und BTRFS-Dedup machen die Marginalkosten nahezu null.
Hoody Cron trägt den Schedule. Hoody Exec trägt die Erneuerungs-Logik. Sonntag um 04:00 feuert ein curl, certbot läuft, das neue Bundle wird per PATCH in den Proxy geschoben, und der Reload wird quittiert. Keine Shell-Session, kein Key in ~/.ssh, kein Jump-Host zwischen dir und dem Zertifikat.
# weekly · Sunday 04:00 0 4 * * 0 bash /scripts/renew.shwöchentlich · einmal POSTed · läuft für immer von selbst
kein SSH-Key · kein Jump-Host · der Schedule ist eine Zeile in einer JSON-API
Die ganze Erneuerungs-Pipeline besteht aus zwei Endpoints und einem 5-Feld-Schedule. Cron triggert Exec. Exec ruft ACME auf und schickt PATCH an den Proxy. Die Quittung kommt als 200 zurück.
POST /users/me/entries mit schedule "0 4 * * 0" und command "curl /scripts/certs/renew". Der Cron-Service schreibt es in die User-Crontab und fängt an zu ticken. Du hast das einmal gemacht, von irgendwo mit HTTPS.
Sonntag 04:00 curlt der Cron die Exec-URL. Exec startet das Skript, redet mit dem ACME-Endpoint von Let's Encrypt, validiert den http-01-Challenge und schreibt das erneuerte Bundle nach /files. Niemand loggt sich auf einer Node ein, keine Session nötig.
Das Skript schickt das neue Zertifikat und den Key per PATCH an den Bundle-Endpoint des Hoody-Proxys. Der Proxy lädt heiß nach — kein Restart — und der nächste TLS-Handshake liefert das neue Zertifikat aus. Der ganze Zyklus dauert unter einer Minute.
Jeder Schritt ist ein HTTP-Call, den du aus einem Terminal nachspielen kannst — `curl --dry-run` wenn du debuggen willst, `curl -i` wenn du die Header sehen willst. Die Pipeline hängt zu keinem Zeitpunkt von einer eingeloggten Session ab.
Links der Cron-Eintrag, der den Job einplant. Rechts das Exec-Skript, das die Arbeit erledigt. Beide sind über HTTP adressierbar — beide auditierbar, beide von jedem Laptop oder Handy aus replaybar.
# 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 };
Zwei URLs, ein Sonntagmorgen, null SSH. Der Cron-Eintrag ist Daten — POST ihn einmal, und er ist da, bis du DELETE schickst. Das Exec-Skript ist eine Datei — ändere sie über die API, und der nächste Lauf nimmt die neue Logik. Nichts an dieser Schleife verlangt, dass eine Person an einer Maschine sitzt.
Dasselbe Ergebnis — jede Woche ein erneuertes Zertifikat — mit drei Eigenschaften, die das alte Setup nie hatte.
Auth ist ein URL-Token, kein SSH-Key. Rotier ihn über die API, und der alte Token funktioniert überall gleichzeitig nicht mehr. Kein Agent-Forwarding, kein Bastion, keine Key-Datei, von der du vergessen hast, dass du sie vor drei Jahren auf eine CI-Box kopiert hast.
Jeder Lauf ist eine Zeile im Cron-Log und eine Request-Zeile im Exec-Log. Grep, wer es getriggert hat, wann, welches Zertifikat, welcher Response-Code. Die 200 vom Proxy ist die Quittung, dass der Reload angekommen ist.
Spiel die Erneuerung von deinem Laptop aus mit `curl /scripts/certs/renew?dry_run=true` nach. Schau dir die Antwort an, fix das Skript über die Exec-Write-API, versuch's nochmal. Die ganze Schleife läuft über HTTPS — dieselbe Leitung, die der Produktions-Schedule benutzt.
Zahlen aus dem Deployment, keine Benchmarks. Die Form ist, was zählt: sehr wenige bewegliche Teile, alle sprechen HTTP.
Setup ist ein POST. Erneuerung ist ein GET nach Schedule. Debug ist ein curl. Es gibt zu keinem Zeitpunkt eine Shell-Session in der Pipeline — dein Private Key muss nie auf der Box liegen.
Ein Cron-Eintrag, um den Lauf zu planen. Eine Exec-Route, die das Skript ausführt. Die dritte URL — der Proxy-Bundle-PATCH — lebt im Skript und lädt das Zertifikat neu.
Standard-5-Feld-Ausdruck "0 4 * * 0" — Sonntag 04:00. Oder `@weekly`, wenn dir der Tag egal ist. Der Cron-Service akzeptiert beides, plus Auto-Expiration für One-Shot-Erneuerungen.
Cron-Service: 5-Feld-Ausdrücke und Macros (`@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`), Pro-User-Isolation, optionales `expires_at`. Exec: V8-Isolates, Bun-Runtime, Magic Comments für Mode/Timeout/CORS. ACME-Flow läuft in deinem Skript — Hoody führt certbot nicht für dich aus, Hoody führt deinen Code nach Schedule aus.
Erneuerung ist ein curl nach Schedule — keine Shell-Session, kein Key, kein Jump-Host.
Die üblichen Wege, um TLS in Produktion gültig zu halten. Jeder davon will entweder eine Shell-Session, einen Control-Plane-Service oder beides. Das Cron-plus-Exec-Paar will keines von beiden.
Hör auf, dich einzuloggen, um Zertifikate zu erneuern. POSTe den Schedule einmal. Schau zu, wie sich der Proxy jeden Sonntagmorgen selbst neu lädt.