Workaround für Wartungsseite – ist das möglich?

Bei meinem Update ist ein Fehler aufgetreten

api_key = "a quick brown fox"
fetch("https://api.example.com/data", headers: { 'Authorization' => api_key })

Bitte helft mir, dies zu beheben.

Hey!

Ich beantworte deine Frage nicht, ich bin nur neugierig. Warum denkst du, dass du eine Wartungsseite brauchst? Das scheint ziemlich lästig einzurichten, dafür wenig Nutzen zu bringen.

Meine Instanzen sind fünf Minuten im Monat wegen Updates down, und das ist im Grunde alles.

Jedes Mal, wenn ich größere Änderungen vornahm, zum Beispiel das Installieren von Plugins, dauerte es manchmal 20 Minuten.

Das ist kein großes Problem, wenn man bedenkt, dass das nicht jede Woche oder sogar jeden Monat passiert. Aber für einen neuen Besucher ist diese hässliche Seite, die darauf hinweist, dass etwas nicht funktioniert, kein guter erster Eindruck. Selbst für wiederkehrende Besucher, die nicht wissen, dass die Website offline ist, kann das in den „Panikmodus“ versetzen, in dem sie denken, die ganze Community sei abgeschaltet oder so. Vielleicht mailen einige von ihnen mir sofort, um zu fragen, was los ist.

Ich denke, es ist einfach ein netter Gedanke, dem Besucher, neu oder alt, mitzuteilen, was gerade passiert.

Wenn dieser von Claude vorgeschlagene Ansatz nur ein paar Minuten in Anspruch nimmt, aber danach nicht mehr angefasst werden muss, glaube ich, ist die Zeit gut investiert.

Es dauert nur Sekunden, wenn du zur Installation mit zwei Containern wechselst.

Du kannst den Wechsel sogar nachts planen, wenn du möchtest, während du und/oder dein Hauptpublikum schläfst.

Du brauchst keine Wartungsseite.

Ich nutze den Dual-Container-Build hinter einem Cloudflare-CDN. Der Dual-Container minimiert die Ausfallzeit, und meine beiden Haupt-Produktionsforen haben während der Neuaufbau-Prozesse maximal 30 Sekunden Ausfallzeit. Ich mag eine Wartungsseite, weil die Standard-Webserver-Ausfallseite hässlich ist und keinen Hinweis darauf gibt, wie lange die Seite offline sein wird.

Zum Beispiel verwende ich für eine Site unter your-domain.com einfach einen Cloudflare-Worker-Route, der auf *yourdomain.com/* gesetzt ist (inklusive der Sternchen).

Schritt 1: Die Worker-Seite erstellen

Du kannst die Wartungsseite auf der Workers & Pages-Einstellungsseite bei Cloudflare einrichten – klicke auf die Schaltfläche Anwendung erstellen:

und verwende dann die Hello-World-Vorlage:

Gib ihr dann einen Namen und klicke auf Bereitstellen:

Gehe dann zur Übersichtsseite dieser Wartungsseite und klicke auf Code bearbeiten:

und füge diesen Code in das worker.js-Code-Fenster ein (ersetze deine Domain und die Nachricht, die du möchtest; bearbeite Text, Textfarbe, Hintergrund usw.):

export default {
  async fetch(request, env, ctx) {
    try {
      // Hole die ursprüngliche Anfrage von deinem Server
      const response = await fetch(request);

      // Wenn DEINE SITE Container wechselt, wirft sie einen 502, 521 oder 530
      if (response.status === 502 || response.status === 521 || response.status === 530) {
        return returnCustomErrorPage();
      }

      // Wenn alles in Ordnung ist, gib den normalen Forum-Verkehr zurück
      return response;
    } catch (e) {
      // Wenn der Server komplett unerreichbar ist
      return returnCustomErrorPage();
    }
  }
};

function returnCustomErrorPage() {
  const html = `
    <!DOCTYPE html>
    <html lang="de">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Systemaktualisierung - YOUR-SITE.com</title>
      <style>
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; text-align: center; padding: 50px; color: #333; background-color: #f9f9f9; }
        h1 { font-size: 2.5em; margin-bottom: 0.5em; color: #9400D3; }
        p { font-size: 1.2em; line-height: 1.5; }
        .container { max-width: 600px; margin: 0 auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
      </style>
    </head>
    <body>
      <div class="container">
        <h1>Nur ein kurzes Aktualisierungsfenster</h1>
        <p><strong>YOUR-SITE</strong> durchläuft eine kurze Systemaktualisierung von 30 Sekunden.</p>
        <p>Nimm einen Schluck von deinem Getränk – diese Seite wird sich automatisch aktualisieren, sobald wir wieder online sind.</p>
      </div>
      <script>
        // Überprüfe automatisch alle 10 Sekunden, ob die Site wieder verfügbar ist
        setInterval(function() {
          window.location.reload();
        }, 10000);
      </script>
    </body>
    </html>
  `;

  return new Response(html, {
    status: 503, // 503 ist am besten für SEO, damit Google dich nicht für Ausfallzeiten bestraft
    headers: {
      "Content-Type": "text/html;charset=UTF-8",
      "Retry-After": "30"
    }
  });
}

Es sollte ungefähr so aussehen. Klicke auf Bereitstellen, um es zu speichern:

Schritt 2: Die Route hinzufügen

Gehe nun zur Cloudflare-Worker-Route-Seite und klicke auf die Schaltfläche Route hinzufügen, um das neue Route-Modal aufzurufen. Fülle die Domain-Route aus und wähle die Worker-Seite, die du gerade erstellt hast, und klicke dann auf Speichern:

Schritt 3: Updates oder Neuaufbau ausführen

Wenn du dich nun per SSH mit deinem Server verbindest und Systemupdates durchführst oder einen Neuaufbau startest, wird anstelle einer Website-down- oder Fehlerseite diese Seite angezeigt, wenn die Ausfallzeit tatsächlich eintritt (ich verwende in meiner Konfiguration 30 Sekunden, da dies das Maximum für meine Sites ist).

Ich füge meine Worker-Route-Seite hinzu und lösche sie wieder, wann immer ich Wartungsarbeiten durchführe, aber manche lassen sie einfach die ganze Zeit dort (ich lasse den eigentlichen Code für die Seite, füge nur die Route hinzu und entferne sie wieder).

Ich denke, das war’s.

Optional: Updates mit einem Skript ausführen und planen

Ich verwende auch ein Unix-Shell-Skript auf meinem Server, um das Dual-Container-spezifische Update auszuführen, das ich wie folgt erstellt habe:

cat << 'EOF' > /root/update-web.sh
#!/bin/bash
cd /var/discourse
echo "➡️ Ziehe neueste Discourse-Docker-Skripte..."
git pull

echo "➡️ Bootstrap neuer Web-Container im Hintergrund (dauert ca. 8 Min)..."
./launcher bootstrap web_only

if [ $? -eq 0 ]; then
    echo "✅ Bootstrap erfolgreich! Container werden gewechselt..."
    ./launcher destroy web_only && ./launcher start web_only
    echo "🚀 Fertig! Site mit nahezu null Ausfallzeit aktualisiert."
else
    echo "❌ Bootstrap fehlgeschlagen! Wechsel wird abgebrochen, um die aktuelle Site online zu halten."
fi
EOF

chmod +x /root/update-web.sh

Dann führe ich es am Root-Prompt auf meinem Server mit dem Befehl ./update-web.sh aus.


:warning: Bearbeitung: Führe die untenstehenden Schritte nicht aus, es sei denn, du hast ein bezahltes Cloudflare-Konto.

Du kannst es zu einer bestimmten Zeit automatisieren, z. B. 1 Uhr morgens sonntags in deiner lokalen Zeitzone mit einem Cron-Job. Für mich ist 1:00 Uhr lokal 8:00 Uhr UTC (du kannst das UTC-Datum deines Servers herausfinden, indem du date am Befehlszeilen-Prompt eingibst, wenn du per SSH verbunden bist).

Also:

Führe diesen Befehl aus, um den Aufgabenplaner deines Servers zu öffnen:

crontab -e

(Wenn du aufgefordert wirst, einen Editor auszuwählen, wähle deinen bevorzugten Editor, 1 für nano ist wahrscheinlich am einfachsten)

Ich scrolle zum Ende der Kommentare und füge dies ein:

0 8 * * 0 /root/update-web.sh >> /var/log/discourse-update.log 2>&1

(was bedeutet, führe die Datei /root/update-web.sh um Minute 0, Stunde 8 (UTC), jeden Sonntagmorgen aus)

Dann speichern und beenden (wenn du nano verwendest):

  1. Ctrl + O zum Speichern.
  2. Enter zur Bestätigung.
  3. Ctrl + X zum Beenden.

Dann kann ich cat /var/log/discourse-update.log ausführen, wenn ich sonntags morgens aufwache, um zu überprüfen, ob es ordnungsgemäß ausgeführt wurde. Wenn du einen Cron-Aufgabenplaner verwendest, solltest du die Worker-Seiten-Route lassen.

Ich denke, das war alles. Lass es mich wissen, wenn du Fragen hast lol. Es ist viel einfacher, als ich es erscheinen ließ lol. :grin:

Wow! Ich schätze diese detaillierte Anleitung wirklich sehr! :raising_hands:
Ich habe deine Antwort gerade in meine Notizen gespeichert, damit ich darauf zurückgreifen kann, wenn ich Discourse in Kürze erneut installiere. Ich werde dir auf jeden Fall Bescheid sagen, wie es gelaufen ist, auch wenn es eine Weile dauert, bis ich die Installation durchführe. Im Moment beende ich einige Programmieraufgaben und werde mich danach wieder auf Discourse konzentrieren.

Und ich stimme zu, dass die Seite „Webserver ist nicht erreichbar“ hässlich ist und für unerfahrene Benutzer wenig aussagekräftig. Eine einfache Wartungsseite mit einer individuellen Nachricht ist immer vorzuziehen, auch wenn ihre Einrichtung etwas Aufwand bedeutet.

Nochmals vielen, vielen Dank, dass du dir die Zeit genommen hast, dies zu teilen. Ich hoffe, andere werden ebenfalls davon profitieren :slight_smile:

Und genau da liegt das Problem.

Es ist keine einfache Änderung, und es bedeutet zusätzliche Infrastruktur, um die man sich sorgen und die man warten muss. Meiner Meinung nach ist es für ein paar Sekunden Ausfallzeit einfach nicht wert.

Ich verstehe, was du meinst, aber das ist nur ein Fall. Was ist, wenn wirklich etwas kaputtgeht und ich es reparieren muss, was länger als nur ein paar Sekunden dauert?

Außerdem, wie bekommst du nur ein paar Sekunden Ausfallzeit, während ich nach der Installation von Plugins etwa 20 Minuten sah?

Weil du im Zwei-Container-Setup (auf das in beiden unseren Beiträgen verwiesen wird und das eine unverzichtbare Abhängigkeit darstellt) den neuen Build mit ./launcher bootstrap web_only initialisierst (währenddessen deine Site zu 100 % funktionsfähig bleibt), und dann einfach den alten Container zerstörst und sofort den neu erstellten, bereits gebauten Container startest (was nur Sekunden dauert).

Oh, okay, das gilt also immer noch für die 2-Container-Konfiguration. Ich dachte, du würdest sagen, dass sich der Aufwand, die 2-Container-Konfiguration vollständig aufzubauen, nicht lohnt. Was du meinst, ist, dass sich nur der zusätzliche Aufwand für die Wartungsseite nicht lohnt, oder?

Persönlich ja.

Wenn du für Webnutzer, die in den ersten 30–60 Sekunden mit einer neuen Navigation erscheinen, Sicherheitshalber Absicherungen möchtest, ist eine Wartungsseite angemessen.

Du musst den Nutzen davon gegen den Aufwand abwägen, die zugrunde liegende Infrastruktur zu warten.

Jetzt verstehe ich. Danke.

Also frage ich jetzt: Bei zwei Containern sind diese etwa 20 Minuten immer noch ein Thema, der einzige Unterschied ist, dass ich es auf einem der Container ausführen lassen kann, dem, der nicht live ist, und wenn es fertig ist, den Wechsel vornehmen. Funktioniert das so?

Ja, es dauert immer noch eine Weile, bis der Container erstellt ist. Zur Info: Du musst sicherstellen, dass dein Server leistungsstark genug ist, um diesen Prozess parallel zur normalen Bedienung deiner Community durchführen zu können (im Grunde ist das Wichtigste zunächst, genügend Arbeitsspeicher zur Verfügung zu haben – daher ist es sehr wichtig, dass du ausreichend SWAP hast). Der Build-Prozess wird zudem mindestens einen Kern vollständig auslasten, also denk daran, einen Server mit einem oder zwei zusätzlichen Kernen zu verwenden.

Jetzt ergibt alles Sinn. Vielen Dank.

Anfangs habe ich dies verwendet, aber es scheint, als wäre es nicht mehr verfügbar:

Also muss ich jetzt zu diesem wechseln:

Das ist ein ziemlicher Preissprung… :confused: und was wie ein weniger leistungsstarker Server aussieht…?

Für eine solche Konfiguration würde ich mindestens 4 GB und 3 Kerne („vcpu“) empfehlen …

Zur Referenz, da dies in einem anderen Thema gefragt wurde, die (Bearbeitung: falsche) Antwort: Any cheaper alternatives to Hetzner? - #2 by Canapin

Das ist das einzige, das dazu passt… welch ein Preisunterschied…

image

Ich nehme an, ich muss es jetzt mit einem Container aufbauen und wenn die Zeit (:money_bag:) reif ist, upgraden.

Danke für die Info, Robert!

Ich bin anderer Meinung und finde, dass sich die Wartungsseite lohnt. Aus meiner Erfahrung heraus, wenn Leute die Discourse-Fehlerseite sehen, ist das Erste, was sie tun, dass sie auf Aktualisieren klicken, und dann sehen sie die kurze Wartungsseite, die die Website automatisch neu lädt, sobald der Containerwechsel abgeschlossen ist. Es ist nicht viel Arbeit, sie einzurichten, und du musst es nur einmal tun. Während eines Neuaufbaus mit der Dual-Container-Konfiguration findet der Bootstrap-Prozess im Hintergrund statt, und Benutzer können die Website weiterhin nutzen; es ist der Containerwechsel, der die kurze Ausfallzeit verursacht (im Gegensatz zu einer Standard-Einzelcontainer-Konfiguration).

Serverkosten und -auswahl sind etwas ganz anderes und sollten in einem separaten Thema behandelt werden.

Ich schätze, ich bin gerade in der Mitte. Ich verstehe, was du meinst, genauso wie @merefield. Es ist eine nette Geste, es zu haben, und wenn es nur einmal eingerichtet wird, ist es wahrscheinlich kein großes Problem, oder?

Gleichzeitig, wenn es tatsächlich bis zu 60 Sekunden dauern kann, im schlimmsten Fall, wird nicht jeder genau zur Sekunde 0 auf die Website zugreifen und 60 Sekunden warten müssen. Einige werden die hässliche Seite für 5 Sekunden sehen, andere für 20, andere für 60. Einige werden sie vielleicht gar nicht sehen (ich glaube?), zum Beispiel wenn sie gerade eine Antwort lesen oder eine schreiben; dieser Wechsel könnte passieren, bevor sie auf SENDEN klicken oder bevor sie aufhören, das Thema zu lesen, und auf ANTWORTEN klicken (oder eine andere Seite besuchen).

Mein Problem mit der nginx-Route war eher mit der 20-Minuten-Sache bei einer Ein-Container-Einrichtung verbunden. Mit der Option, 2 Container zu haben, und von 20 Minuten auf vielleicht maximal 60 Sekunden zu gehen, frage ich mich, ob es wirklich relevant ist? Vor allem, wenn ich in der Lage bin, einen Hinweis oben hinzuzufügen, der sagt, dass die Dinge nur für ein paar Sekunden ausgefallen sein werden, zu einer Zeit mit wenig Traffic, wird das kein großes Problem sein?

Ich muss mich hinsetzen und darüber nachdenken. Die Zwei-Container-Einrichtung wird auf jeden Fall etwas sein, das ich implementieren werde, wenn ich ein gutes Server-Angebot finde.

Könntest du das bitte so erklären, dass es auch für Laien wie mich verständlich ist? Ich kenne mich mit Workers noch nicht so gut aus…

Warum fügst du die Worker-Routen-Seite hinzu und löschst sie wieder, wenn es kein Problem ist, sie einfach liegen zu lassen? Also, wenn ich die Wartungsseite hinzufüge, kann ich sie dann wirklich nur einmal einrichten und ab diesem Moment meinen Server immer nur per SSH über das Terminal verwalten – genau wie bei einem einzelnen Container – ohne jemals wieder zu Cloudflare gehen zu müssen?

@merefield hat erwähnt, dass auch diese Komponenten (Wartungsseite, Workers usw.) gewartet werden müssen. Ich frage mich also, ob man das wirklich einmal einrichtet und dann vergisst, oder ob man von Zeit zu Zeit noch etwas tun muss?