Blog

Ein fehlgeschlagenes Republish löscht nie ein funktionierendes Backend

Am 25. September hat ein fehlgeschlagenes Republish das Backend einer App gelöscht, das rund zweieinhalb Stunden live und funktionsfähig gewesen war. Der Code, der einen fehlgeschlagenen Publish rückgängig macht, entfernte jede Server-App, die der Publish berührt hatte, auch solche, die schon vorher ausgeliefert wurden. Jetzt werden nur noch Apps gelöscht, die ein Publish selbst angelegt hat. Eine bereits bestehende App wird auf genau das Image zurückgesetzt, das sie vorher lief. Zwei Folgekorrekturen am selben Tag sorgten dafür, dass das Zurücksetzen auch läuft, wenn das Deploy-Werkzeug der Hosting-Plattform selbst fehlschlägt, und dass eine gesunde App nicht als fehlerhaft gilt, nur weil sie geschlafen hat.

So wird ein Backend veröffentlicht

Wenn deine Mythex-App ein Backend hat, also eine API oder einen Server und nicht nur statische Dateien, baut der Publish es aus einem Dockerfile (einem Rezept, das die App in ein Image verpackt) und rollt dieses Image auf Maschinen unserer Hosting-Plattform aus. Danach wartet ein Health-Check, bis die neue Version tatsächlich hochgefahren ist und stabil läuft, bevor der Publish als live markiert wird.

Schlägt unterwegs etwas fehl, läuft ein Rollback, das es rückgängig macht. Dieses Rollback richtig hinzubekommen ist wichtiger als fast alles andere beim Publizieren, denn es läuft genau dann, wenn schon etwas schiefgeht.

Problem 1: Das Rollback löschte, was es hätte wiederherstellen sollen

Das Rollback führte eine Liste der Server-Apps, auf die ein Publish deployt hatte, und zerstörte bei einem Fehler jede davon. Bei einem Erst-Publish ist das richtig: Die App wurde gerade eben angelegt, nichts hängt von ihr ab, und das Löschen stellt den vorherigen Zustand wieder her.

Bei einem Republish ist es genau falsch. Die App existierte bereits und bediente echte Besucher. Am 25. September wurde die API einer App, die rund zweieinhalb Stunden live gewesen war, durch ein fehlgeschlagenes Republish gelöscht.

Im selben Code steckte ein zweiter Fehlermodus. Wenn das Löschen nicht durchging, blieb das kaputte neue Image auf den Maschinen, während wir dem Besitzer mitteilten, seine aktuelle Seite sei weiterhin live. Bis der Health-Check fehlschlagen kann, ist das neue Image bereits auf jede Maschine ausgerollt. Nichts zu tun ist nicht dasselbe, wie etwas rückgängig zu machen.

Die Lösung: nur löschen, was man selbst angelegt hat, den Rest wiederherstellen

Jeder Publish hält jetzt für jede Server-App, die er berührt, zwei Dinge fest:

  • ob dieser Publish sie angelegt hat, und
  • falls nicht, welches Image sie kurz vorher ausgeführt hat.

Bei einem Fehler bekommt jede App eine von drei Behandlungen:

  1. Von diesem Publish angelegt: wie bisher löschen.
  2. Schon vorhanden, bisheriges Image bekannt: das bisherige Image mit derselben Konfiguration erneut ausrollen. Kein Build, nur das Image wird zurückgesetzt.
  3. Schon vorhanden, bisheriges Image unbekannt: unangetastet lassen. Eine bestehende App wird nie gelöscht, auch dann nicht, wenn wir sie nicht wiederherstellen können.

Diese Regeln sind eine kleine reine Funktion mit eigenen Tests, damit die Entscheidung nicht unbemerkt zurück zu „alles löschen“ driftet.

Problem 2: Das Deploy-Werkzeug konnte scheitern, bevor wir festgehalten hatten, wie man zurückrollt

Kurz nach dieser Korrektur fanden wir eine Lücke darin. Das Deploy-Werkzeug der Hosting-Plattform führt eigene Smoke-Tests aus: Stürzen die neuen Maschinen ab, bricht es mit einem Fehler ab. Das passiert aber nachdem das neue Image schon auf den Maschinen liegt.

Unser Code hatte eine App erst dann für das Rollback registriert, wenn das Werkzeug erfolgreich zurückgekehrt war. Scheiterte das Werkzeug selbst am Deploy, stand die App noch nicht auf der Rollback-Liste, und es wurde nichts wiederhergestellt. Auf unserer Staging-Umgebung blieb nach einem fehlerhaften Republish das kaputte Image aktiv.

Die Lösung: den Rückweg festhalten, bevor man startet

Die App wird jetzt für das Rollback registriert, mit der Information, ob sie angelegt wurde und welches Image sie ausgeführt hat, sobald sie vorbereitet ist und bevor irgendetwas auf sie ausgerollt wird. Was danach auch fehlschlägt, das Rollback weiß, was es zurücksetzen muss. Lokal geprüft: Ein fehlerhaftes Republish scheiterte an den Smoke-Tests des Deploy-Werkzeugs, und die vorherige Version beantwortete weiterhin Anfragen.

Problem 3: Eine schlafende App wurde als „nie gestartet“ gewertet

Veröffentlichte Apps auf Mythex schlafen, wenn sie untätig sind, um deine Credits zu schonen. Ein Republish lässt eine schlafende Maschine angehalten zurück, deshalb muss der Health-Check sie wecken. Er bat die Plattform einmal, die Maschine zu starten, und ignorierte die Antwort.

Am 25. September ging diese eine Startanfrage ins Leere. Eine gesunde API blieb die volle fünfminütige Health-Check-Zeit angehalten und wurde mit „1 Maschine nie gestartet (letzter Status: angehalten)“ als fehlgeschlagen gewertet.

Die Plattform verweigert einen Start manchmal tatsächlich. Beim Nachstellen des Problems kam ohne unser Zutun ein Konflikt „lease currently held“ zurück, und Starts werden verweigert, solange eine Maschine aktualisiert wird.

Die Lösung: weiter nachfragen und anklopfen

Der Health-Check macht jetzt Folgendes:

  • Er fragt während des Wartens alle 20 Sekunden erneut, ob eine angehaltene Maschine startet.
  • Er protokolliert, was die Plattform antwortet, wenn sie einen Start verweigert.
  • Er schickt eine ganz normale Anfrage an die App, so wie ein Besucher es täte. Der Proxy der Plattform weckt eine schlafende Maschine, sobald eine Anfrage eintrifft.

Wir haben das auf der echten Plattform mit einer Wegwerf-App nachgestellt, deren erster Start abgelehnt wurde. Vor der Korrektur scheiterte der Publish nach 91 Sekunden. Danach wurde er in 20 Sekunden veröffentlicht. Eine App, die beim Hochfahren tatsächlich abstürzt, schlägt weiterhin fehl, wie es sein soll.

Was wir daraus gelernt haben

  • Ein Rollback muss zwischen neu und bestehend unterscheiden. „Rückgängig machen“ heißt bei etwas, das du angelegt hast, löschen. Bei etwas, das schon da war, heißt es wiederherstellen. Beides gleich zu behandeln ist der Weg, auf dem eine Sicherheitsfunktion eine funktionierende App löscht.
  • Schreib vor dem Handeln auf, wie man zurückrollt. Wird der Rückweg erst nach einem erfolgreichen Schritt festgehalten, hinterlässt ein Schritt, der auf halbem Weg scheitert, nichts, womit man zurückrollen könnte.
  • Verschluck nie die Antwort auf eine Anfrage, von der du abhängst. Ein ignoriertes „Nein“ hat aus einer gesunden App einen fehlgeschlagenen Publish gemacht.

Eine verwandte Korrektur vom selben Tag: Apps erkennen, die direkt nach dem Publizieren abstürzen. Was passiert, wenn ein Publish auf deiner Seite fehlschlägt, steht in der Publish-Fehlerbehebung in der Dokumentation.

Mythex · Pricing · Alles mit KI bauen · Vorlagen für Websites und Apps · Mythex im Vergleich · Glossar zum App-Bau mit KI · Kostenlose Tools für den App-Bau mit KI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)