Blog

Een mislukte herpublicatie verwijdert nooit een werkende backend

Op 25 september verwijderde een mislukte herpublicatie de backend van een app die bijna tweeëneenhalf uur lang live en werkend was geweest. De code die een mislukte publicatie ongedaan maakt, haalde elke server-app weg die de publicatie had aangeraakt, ook de apps die al draaiden voordat die begon. Nu worden alleen apps die een publicatie heeft aangemaakt ooit verwijderd; een app die al bestond, wordt teruggezet op precies de versie die hij daarvoor draaide. Twee vervolgfixes diezelfde dag zorgden ervoor dat die ongedaanmaking ook loopt wanneer de eigen deploy-tool van het hostingplatform faalt, en dat een gezonde app niet als mislukt wordt gemarkeerd alleen omdat hij sliep.

Hoe een backend wordt gepubliceerd

Als je Mythex-app een backend heeft — een API of server, en niet alleen statische bestanden — dan bouwt publiceren die backend vanuit een Dockerfile (een recept om de app in een image te verpakken) en rolt het die image uit naar machines op ons hostingplatform. Daarna wacht een health check tot de nieuwe versie echt is opgestart en stabiel draait voordat de publicatie als live wordt gemarkeerd.

Als er onderweg iets misgaat, draait een rollback om dat ongedaan te maken. Die rollback goed laten werken is belangrijker dan bijna al het andere bij publiceren, omdat hij precies draait wanneer er al iets fout gaat.

Probleem 1: de rollback verwijderde wat hij had moeten herstellen

De rollback hield een lijst bij van de server-apps waar een publicatie naartoe had uitgerold, en bij een fout vernietigde hij er elke. Dat is juist bij een eerste publicatie: de app is net aangemaakt, niets hangt ervan af, en verwijderen laat de zaak zoals ze was.

Bij een herpublicatie is het precies verkeerd. De app bestond al en diende echte bezoekers. Op 25 september werd de API van een app die al ongeveer tweeëneenhalf uur live was, verwijderd door een mislukte herpublicatie.

In dezelfde code zat een tweede faalwijze verborgen. Als het verwijderen niet lukte, bleef de kapotte nieuwe image op de machines staan — terwijl we de eigenaar lieten weten dat zijn huidige site nog live was. Tegen de tijd dat de health check kan falen, is de nieuwe image al op elke machine uitgerold. Niets doen is niet hetzelfde als ongedaan maken.

De fix: alleen wat je zelf hebt aangemaakt verwijderen, de rest herstellen

Elke publicatie legt nu voor elke server-app die ze aanraakt vast:

  • of deze publicatie hem heeft aangemaakt, en
  • als dat niet zo is, welke image hij draaide net voordat.

Bij een fout krijgt elke app een van drie behandelingen:

  1. Aangemaakt door deze publicatie: verwijderen, zoals voorheen.
  2. Bestond al, vorige image bekend: de vorige image opnieuw uitrollen met dezelfde configuratie. Geen build — alleen de image gaat terug.
  3. Bestond al, vorige image onbekend: met rust laten. Een bestaande app wordt nooit verwijderd, ook niet als we hem niet kunnen herstellen.

Deze regels zijn een kleine pure functie met eigen tests, zodat de beslissing niet terugglijdt naar "alles verwijderen" zonder dat een test faalt.

Probleem 2: de deploy-tool kon falen voordat we hadden vastgelegd hoe we het ongedaan maken

Kort na die fix vonden we een gat erin. De deploy-tool van het hostingplatform draait zijn eigen smoke checks: als de nieuwe machines crashen, stopt hij met een fout. Maar dat doet hij nadat de nieuwe image al op de machines staat.

Onze code registreerde een app pas voor rollback nadat de tool succesvol terugkwam. Wanneer de tool zelf de deploy liet mislukken, stond de app nog niet op de rollbacklijst, dus er werd niets hersteld. Op onze staging-omgeving bleef een kapotte image draaien na een mislukte herpublicatie.

De fix: de ongedaanmaking vastleggen voordat je begint

De app wordt nu voor rollback geregistreerd — met of hij is aangemaakt en welke image hij draaide — zodra hij is voorbereid en voordat er iets op wordt uitgerold. Wat daarna ook faalt, de rollback weet wat hij terug moet zetten. We hebben dit lokaal geverifieerd: een kapotte herpublicatie faalde in de eigen smoke checks van de deploy-tool, en de vorige versie bleef antwoorden.

Probleem 3: een slapende app werd als "nooit gestart" afgekeurd

Gepubliceerde apps op Mythex slapen wanneer ze inactief zijn, om je credits te sparen. Bij een herpublicatie blijft een slapende machine gestopt, dus de health check moet hem wekken. Die vroeg het platform de machine één keer te starten en negeerde het antwoord.

Op 25 september ging dat ene startverzoek nergens heen. Een gezonde API bleef de hele vijf minuten van de health check gestopt en werd afgekeurd met "1 machine never started (last state: stopped)".

Het platform weigert soms een start. Terwijl we dit reproduceerden, gaf het zonder dat we het uitlokten een conflict "lease currently held" terug, en het weigert starts zolang een machine wordt bijgewerkt.

De fix: blijven vragen, en op de deur kloppen

De health check nu:

  • vraagt om een gestopte machine te starten elke 20 seconden zolang hij wacht,
  • logt wat het platform antwoordde wanneer het weigert, en
  • stuurt één gewoon verzoek naar de app, zoals een bezoeker zou doen — de proxy van het platform wekt een slapende machine wanneer er een verzoek binnenkomt.

We hebben dit op het echte platform nagebootst met een wegwerp-app waarvan de eerste start werd geweigerd. Voor de fix faalde de publicatie na 91 seconden. Na de fix werd hij in 20 seconden gepubliceerd. Een app die echt crasht bij het opstarten faalt nog steeds, zoals het hoort.

Wat we ervan geleerd hebben

  • Een rollback moet het verschil kennen tussen nieuw en bestaand. "Ongedaan maken" voor iets wat je hebt aangemaakt is verwijderen. "Ongedaan maken" voor iets wat er al was, is herstellen. Ze hetzelfde behandelen is hoe een veiligheidsmechanisme een werkende app verwijdert.
  • Leg vast hoe je iets ongedaan maakt voordat je handelt. Als de ongedaanmaking alleen wordt vastgelegd nadat een stap slaagt, laat een stap die halverwege faalt niets over om mee terug te draaien.
  • Negeer nooit het antwoord op een verzoek waar je van afhangt. Eén genegeerd "nee" maakte van een gezonde app een mislukte publicatie.

Een verwante fix van diezelfde dag: apps opvangen die direct na publiceren crashen. Wat er gebeurt als een publicatie aan jouw kant mislukt, lees je in de publicatie-probleemoplossing in de docs.

Mythex · Pricing · Bouw alles met AI · Website- en app-templates · Mythex vergeleken · Woordenlijst voor apps bouwen met AI · Gratis tools voor apps bouwen met AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά 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 ਪੰਜਾਬੀ 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 简体中文 繁體中文(香港) 繁體中文(台灣)