Sharing: eine grundlegende Methode, um eine Holding-Seite beim Upgrade einzurichten

Hinweis: Ich bin mir nicht sicher, wo ich das platzieren soll. Bitte verschieben Sie es an einen geeigneteren Ort, falls ich etwas übersehen habe.

Ich wollte nur eine schnelle, provisorische Methode teilen, die ich in der letzten Woche entwickelt habe, um während eines Discourse-Upgrades eine schnelle Seite anzuzeigen. Ich habe alle vorhandenen Anleitungen gelesen, aber ich habe keine Ahnung von nginx und ein Dual-Container-Setup sah sehr einschüchternd aus.

tl;dr; Ich habe etwas gemacht, der Code ist unten. :backhand_index_pointing_down:

Node.js zur Rettung

Da dachte ich: Was ist der schnellste Weg, einen winzigen Webserver mit einer einzigen Seite zu starten? Dann erinnerte ich mich, dass Node.js sowieso installiert war. Könnte ich vielleicht nur das verwenden?

Eine schnelle Suche und ein Copy/Paste von Stackoverflow später hatte ich ein winziges Ding, das auf Port 80 lauschte!

Der Prozess ist sehr manuell, aber ich denke, es ist in Ordnung. Ich muss das Logging während des Upgrades sowieso überwachen, also warte ich auf das Signal:

Stopping old container
+ /usr/bin/docker stop -t 600 app

Zu diesem Zeitpunkt hätte ich eine weitere SSH-Sitzung geöffnet, in der ich schnell Folgendes ausführe:

touch index.html
node server.js 80

Ich erstelle die Datei index.html mit touch, damit ich das Update-Datum daraus lesen und einen Platzhalter ersetzen kann. In meiner index.html habe ich diese Zeile:

<p>Diese Seite wurde zuletzt aktualisiert um: LASTUPDATE</p>

In der Datei server.js ersetze ich LASTUPDATE durch das Datum/die Uhrzeit, zu der die Datei index.html zuletzt aktualisiert wurde. Dies gibt den Leuten eine Vorstellung davon, wann das Upgrade begonnen hat, und ich weise auf der Seite darauf hin, dass es 10-15 Minuten dauern wird.

Damit konnte ich auf meinem Dev-Server leicht etwas als Test laufen lassen und fühlte mich bereit, dies live zu tun.

Oops, wir brauchen https :sweat_smile:

Zeit, den Live-Server zu aktualisieren und den Leuten meine neue schnelle Wartungsseite zu zeigen!

Das lief nicht wie erwartet. Die Live-Seite ist hinter Cloudflare und erfordert vollständige End-to-End-Zertifikate. Also habe ich das Forum 15 Minuten lang offline genommen und nur eine Cloudflare-Fehlerseite angezeigt :person_facepalming:

Glücklicherweise halfen weitere Copy/Paste-Aktionen von Stack Overflow. Ich habe den Server von http auf https umgestellt und die Dateien cert.key und cert.pem erhalten, um sicherzustellen, dass die Zertifikatskette intakt war.

Das nächste Upgrade war ein größerer Erfolg und die Wartungsseiten erschienen wie gewünscht:

Zeigen Sie mir einfach den Code!

Hier sind die beiden Dateien, die ich für diese Wartungsseite verwende:

index.html

<!DOCTYPE html>
<html lang="en-US">
<head>
        <meta charset="utf-8">
        <title>We'll be right back</title>
</head>
<body>
        <h1>We'll be right back</h1>
        <p>Sorry for the temporary outage, we're currently applying an update, this usually take 10-15 minutes.</p>
        <p>This page was last updated at: LASTUPDATE</p>
</body>
</html>

server.js

var http = require("http"),
  https = require("https"),
  url = require("url"),
  path = require("path"),
  fs = require("fs"),
  port = process.argv[2] || 81;

const options = {
  key: fs.readFileSync("cert.key").toString(),
  cert: fs.readFileSync("cert.pem").toString(),
};

https
  .createServer(options, function (request, response) {
    var uri = url.parse(request.url).pathname,
      filename = path.join(process.cwd(), uri);

    fs.exists(filename, function (exists) {
      if (!exists) {
        response.writeHead(404, { "Content-Type": "text/plain" });
        response.write("404 Not Found\n");
        response.end();
        return;
      }

      let indexFile = (filename += "index.html");
      if (fs.statSync(filename).isDirectory()) indexFile;

      fs.readFile(filename, "utf8", function (err, file) {
        if (err) {
          response.writeHead(500, { "Content-Type": "text/plain" });
          response.write(err + "\n");
          response.end();
          return;
        }

        var stats = fs.statSync(indexFile);
        var mtime = stats.mtime;

        response.writeHead(200);
        file = file.replace(/LASTUPDATE/g, mtime);
        response.write(file, "utf8");
        response.end();
      });
    });
  })
  .listen(parseInt(port, 10));

console.log(
  "Static file server running at\n  => https://localhost:" +
    port +
    "/\nCTRL + C to shutdown"
);

Wie oben erwähnt, können Sie es wie folgt ausführen:

touch index.html
node server.js 443

Das Argument 443 ist der Port, auf dem Sie es ausführen möchten. Standardmäßig läuft es auf Port 81, damit ich einen curl-Befehl ausführen kann, um die Ausgabe zu testen, bevor ich dies tatsächlich während des Upgrades tue:

curl -k https://localhost:81

Irgendwann während des Discourse-Upgrades, wenn es abgeschlossen ist, sehen Sie:

Error starting userland proxy: listen tcp4 0.0.0.0:443: bind: address already in use.

Das ist, wenn ich den Node-Server beende und Discourse neu starte:

./launcher restart app

Und das ist alles. Ich hoffe, das hilft jemandem!

3 „Gefällt mir“