gooddeploy
Handbuch · Kapitel 2

Deploy, Preview, Promote, Rollback

Der Kern von gooddeploy in vier Befehlen: Stand hochladen und als Vorschau (Preview) bauen, prüfen, live schalten und bei Bedarf in Sekunden zurück.

Der Ablauf auf einen Blick

git commit -am "Neue Startseite"
gooddeploy deploy        # baut eine Preview und zeigt ihre Adresse
gooddeploy promote       # schaltet die neueste Preview live
gooddeploy rollback      # zurück auf die vorherige Live-Version

Jedes deploy erzeugt ein Deployment mit einer kurzen ID aus acht Zeichen, z. B. k7m2q9xa. Diese ID brauchst du für promote, rollback und rm; gooddeploy ls zeigt sie dir.

Deploy: Stand hochladen und Preview bauen

gooddeploy deploy

Was dabei passiert:

  1. gooddeploy prüft dein Git-Repo. Hochgeladen wird genau der letzte Commit (HEAD), nicht deine Arbeitskopie. Deshalb muss alles committet sein; sonst bricht deploy ab und nennt die geänderten Dateien.
  2. Der Commit wird gepackt und direkt beim Packen hochgeladen; im Terminal laufen die hochgeladene Größe und die Rate mit. Git-Submodule und Git LFS werden nicht unterstützt.
  3. gooddeploy baut die Seite, startet sie und prüft, ob sie antwortet. Du siehst jede Phase mit Schrittzähler und Dauer, beim laufenden Schritt einen Spinner mit der Zeit, und die Ergebnisse der Checks (✓ Check health). Vom Build-Log zeigt das Terminal die letzten Zeilen in einem mitlaufenden Fenster; danach steht dort, wie viele Zeilen es waren und wie du sie ansiehst. Das ganze Log dauerhaft bekommst du mit --logs. Hat die Plattform Hinweise zu deinem Build, stehen sie direkt nach dem Upload mit ⚠ da, z. B. wenn in der next.config output: "standalone" fehlt oder eine NEXT_PUBLIC_*-Variable wie ein Geheimnis heißt.
  4. Am Ende steht das Ergebnis im Kasten und darunter die Preview-Adresse, z. B. https://kunde-website--k7m2q9xa.…, und der Befehl zum Live-Schalten. Beides steht außerhalb des Kastens, damit du es ohne Rahmenzeichen kopieren kannst. Die Adresse kannst du teilen, etwa für eine Abnahme beim Kunden.

So sieht das im Terminal aus (die IDs sind bei dir andere):

$ gooddeploy deploy
 gooddeploy deploy   kunde-website  c1fc6ec „Neue Startseite“ (main)

✓ [1/5] Hochgeladen      0,4 s  25 KB  Deployment k7m2q9xa
✓ [2/5] Warteschlange    0,0 s
✓ [3/5] Build             48 s
  ╰ 182 Zeilen Build-Log: gooddeploy logs k7m2q9xa --build
  ✓ Check build
✓ [4/5] Start            1,9 s
✓ [5/5] Health-Check     0,1 s
  ✓ Check health
  ✓ Check smoke

╭────────────────────────────╮
│ ✓ Preview bereit nach 51 s │
╰────────────────────────────╯
  https://kunde-website--k7m2q9xa.gooddeploy.de

  Live schalten  gooddeploy promote k7m2q9xa

In einem Skript, in der CI, in einer Pipe (gooddeploy deploy | tee log.txt) oder in einem schmalen Fenster (unter 80 Spalten) schreibt gooddeploy dieselben Angaben ohne Kästen und ohne Animation, eine Zeile nach der anderen und mit dem ganzen Build-Log (siehe Skripte und CI):

→ kunde-website · c1fc6ec „Neue Startseite“ (main)
✓ Hochgeladen 0,4 s · 25 KB · Deployment k7m2q9xa
✓ Warteschlange 0,0 s
… Build startet
  │ [build] Quellstand laden (Commit c1fc6ec12d54)
  │ …
✓ Build 48 s
…
✓ Preview bereit nach 51 s

  https://kunde-website--k7m2q9xa.gooddeploy.de

  Live schalten: gooddeploy promote k7m2q9xa

Scheitert der Build (Exit-Code 4) oder eine Prüfung (Exit-Code 5), nennt gooddeploy den Grund im Fehlerkasten mit Code und Exit-Code und, soweit die Plattform das Build-Log liefert, die letzten 20 Zeilen daraus.

Brichst du das Warten mit Strg+C ab, endet nur die Anzeige; das Deployment läuft auf dem Server weiter. Weiter zusehen kannst du mit gooddeploy inspect <id> --wait.

Was gebaut werden kann: reines HTML (eine index.html im Repo-Root oder in public/) und Builds mit Vite, Astro oder React. Next.js-Anwendungen kommen später.

Optionen:

OptionWirkung
--dir <ordner>nur diesen Unterordner des Repos deployen (z. B. --dir site); geprüft wird nur, ob dieser Ordner sauber committet ist
--logsdas ganze Build-Log dauerhaft zeigen (im Terminal sonst nur die letzten Zeilen; ohne Terminal steht es immer ganz da)
--no-waitnach dem Upload nicht auf die Preview warten; den Stand zeigt gooddeploy status
--timeout <dauer>höchste Wartezeit, Standard 20m
--streamnur mit --json: zusätzlich Build-Log, Phasen und Checks als JSON-Zeilen (siehe Skripte und CI)

deploy erzeugt immer eine Preview. Eine Option, direkt live zu deployen, gibt es bewusst nicht: Live schaltest du danach mit promote.

Promote: live schalten

gooddeploy promote             # die neueste Preview
gooddeploy promote k7m2q9xa    # ein bestimmtes Deployment

gooddeploy zeigt dir vorher, was jetzt live ist, was live gehen soll und wie die Checks stehen, und fragt nach (j für ja):

 gooddeploy promote   kunde-website

╭─ Plan ────────────────────────────────────────────────────╮
│ Live jetzt  live0001 · 2222222 „Startseite“ (vor 1 h)     │
│ Neu         new00001 · 3f9c2a1 „Kontaktseite“ (vor 5 min) │
│ Checks      alle grün · ✓ build  ✓ health  ✓ smoke        │
╰───────────────────────────────────────────────────────────╯
  Adresse  https://kunde-website.gooddeploy.de
? new00001 live schalten? [j/N]

Live schalten lassen sich Deployments, die „bereit“ sind, und frühere Live-Versionen („abgelöst“ oder „zurückgerollt“). Ohne Terminal (Skripte, CI) brauchst du --yes.

Lehnt gooddeploy das Promote ab (Exit-Code 5), nennt es alle Gründe auf einmal, jeweils mit dem nächsten Schritt:

╭─  FEHLER  ──────────────────────────────────────────────────────────────╮
│ ✗ Promote von new00001 abgelehnt (2 Gründe).                            │
│   ✗ Pflicht-Check „e2e“ fehlt für new00001.                             │
│   ✗ Build-Variablen unterscheiden sich zwischen preview und production: │
│     API_URL.                                                            │
╰─────────────────────────────────────────────────────────────────────────╯
  → Melde ihn mit: gooddeploy checks report new00001 e2e success
  → Setze sie in beiden Umgebungen gleich (gooddeploy env add NAME --both --build) und deploye neu.
  Code REQUIRED_CHECK_MISSING · Exit 5

Die Hinweise mit den Befehlen stehen in derselben Reihenfolge wie die Gründe, unter dem Kasten.

Mögliche Gründe: ein Pflicht-Check fehlt (REQUIRED_CHECK_MISSING) oder ist rot (REQUIRED_CHECK_FAILED), die Build-Variablen von Preview und Produktion unterscheiden sich (BUILD_ENV_MISMATCH, mit den Namen der Variablen, nie den Werten), ein anderes Promote läuft noch (PROMOTE_IN_PROGRESS) oder das Deployment ist nicht bereit (DEPLOYMENT_NOT_READY). Mit --json stehen alle Gründe unter error.details (reasons, missing, failed, variables).

Das Umschalten dauert Sekunden, denn die Version läuft schon: Es wird nichts neu gebaut. Sobald die neue Version live ist, meldet gooddeploy „live nach …“ mit den Live-Adressen und nennt den Weg zurück (gooddeploy rollback <id>).

Optionen:

OptionWirkung
--yes, -yohne Rückfrage (nötig in Skripten)
--waitzusätzlich warten, bis die Prüfung nach dem Umschalten (Verify) fertig ist; läuft sie schon, nur darauf warten
--timeout <dauer>höchste Wartezeit, Standard 10m

Verify: Prüfung nach dem Umschalten

Nach jedem Live-Schalten prüft gooddeploy die Seite noch eine Weile (Verify). Ist die neue Version in dieser Zeit nicht gesund, schaltet gooddeploy automatisch auf die vorherige Version zurück. Du musst dafür nichts tun. Geprüft werden dein Health-Pfad (Standard /, eigener über checks.health.path in gooddeploy.json) und dieselben Smoke-Aufrufe wie vor dem Live-Schalten: ohne Angabe die Startseite /, sonst die Einträge aus checks.smoke mit ihrem erwarteten Status und Text.

  • Ohne --wait endet promote, sobald die Version live ist, und sagt dir, was noch passiert:
  ╭────────────────────────────────────────────────────────────────────────╮
  │ ✓ live nach 2,1 s: new00001                                            │
  │   gooddeploy prüft die neue Version noch 45 s. Bei Fehlern schaltet es │
  │   automatisch auf die vorige Version zurück.                           │
  ╰────────────────────────────────────────────────────────────────────────╯
    https://kunde-website.gooddeploy.de

    Verfolgen  gooddeploy status
    Abwarten   gooddeploy promote new00001 --wait
    Zurück     gooddeploy rollback live0001

Während der Prüfung zeigt gooddeploy status die neue Version unter „Live“ als „live, wird geprüft (noch … s)“. Das Ergebnis siehst du danach ebenfalls mit gooddeploy status; ein automatisches Zurückschalten erscheint dort im Verlauf als auto-rollback. gooddeploy promote <id> --wait während der Prüfung schaltet nichts neu um, sondern wartet nur auf ihr Ende.

  • Mit --wait wartet promote, bis Verify fertig ist; im Terminal läuft dabei ein Balken mit der Restzeit der Prüfung. Am Ende meldet es „Prüfung bestanden“ oder den Fehler VERIFY_FAILED_ROLLED_BACK (Exit-Code 5): Die Version war kurz live, die Plattform hat zurückgeschaltet. Das sieht so aus:
✓ [1/2] Umschalten       1,8 s
✓  LIVE  nach 2,1 s: new00001

  https://kunde-website.gooddeploy.de

✗ [2/2] Prüfen            30 s
╭─  FEHLER  ────────────────────────────────────────────────────────────────╮
│ ✗ Prüfung nach dem Umschalten fehlgeschlagen: new00001 ist zurückgerollt. │
│   Verify fehlgeschlagen, zurückgerollt auf live0001. Verify rot:          │
│   /api/health: Status 503, erwartet 200–399                               │
│   Automatisch zurück auf live0001 … ok (live seit 15:58:15)               │
╰───────────────────────────────────────────────────────────────────────────╯
  → Logs: gooddeploy logs new00001 --since 10m
  Code VERIFY_FAILED_ROLLED_BACK · Exit 5

Rollback: zurück auf die vorherige Version

gooddeploy rollback             # auf die vorherige Live-Version
gooddeploy rollback k7m2q9xa    # auf eine bestimmte frühere Live-Version

Rollback ist der Notausgang und fragt deshalb nicht nach. Es wird nichts neu gebaut; die frühere Version ist in Sekunden wieder live. Danach läuft dieselbe Prüfung (Verify) wie nach einem Promote; --wait und --timeout gibt es auch hier.

Welche Version rollback ohne ID nimmt, zeigt dir gooddeploy status in der Zeile „Rollback“. Gibt es keine frühere Live-Version, bricht rollback mit ROLLBACK_TARGET_UNAVAILABLE ab.

Läuft nach einem promote noch die Prüfung (Verify), schaltet rollback sofort auf die bisherige Live-Version zurück, ohne erneute Prüfung; die gerade geprüfte Version gilt danach als „zurückgerollt“ und lässt sich später wieder live schalten. Ein promote --wait, das auf diese Prüfung wartet, endet dann mit Exit-Code 5.

Rollback setzt das Datenbank-Schema nicht zurück; gooddeploy erinnert dich bei jedem Rollback mit ⚠ Das Datenbank-Schema wird nicht zurückgesetzt. daran und warnt, wenn die Build-Variablen der Version vom heutigen Stand abweichen. Hat die neuere Version die Datenbank verändert (z. B. mit Migrationen), muss die ältere Version damit zurechtkommen.

Live-Seite öffnen

gooddeploy launch                 # Live-Adresse des aktuellen Projekts im Browser öffnen
gooddeploy launch kunde-website   # eines bestimmten Projekts
gooddeploy launch --no-open       # Adresse nur ausgeben

Eigene Domains

Eigene Domains (z. B. www.kunde.de) richtet in der Pilotphase goodDEV für dich ein. gooddeploy status zeigt sie an. Selbst einrichten per CLI kommt später.