Condivisione: un metodo rudimentale per impostare una pagina di mantenimento durante l'aggiornamento

Nota: non sono sicuro di dove inserire questo, sentiti libero di spostarlo in un posto più appropriato se ho trascurato qualcosa.

Volevo solo condividere un modo rapido e “hacky” che ho ideato nell’ultima settimana per creare una pagina temporanea durante l’aggiornamento di Discourse. Ho letto tutte le guide esistenti, ma non so nulla di nginx e una configurazione a doppio container mi sembrava molto intimidatoria.

tl;dr; Ho creato qualcosa, il codice è qui sotto. :backhand_index_pointing_down:

Node.js in soccorso

Allora ho pensato: qual è il modo più veloce per avviare un piccolissimo web server con una singola pagina? Poi mi sono ricordato che node.js era comunque installato, potrei forse cavarmela usandolo semplicemente?

Una rapida ricerca e copia/incolla da Stackoverflow dopo, avevo una piccola cosa in ascolto sulla porta 80!

Il processo è super manuale, ma penso che vada bene, devo comunque monitorare i log durante l’aggiornamento, quindi aspetto di vedere il segnale:

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

A quel punto, avrei un’altra sessione SSH aperta dove eseguo rapidamente:

touch index.html
node server.js 80

Eseguo touch sul file index.html in modo da poter leggere la data di aggiornamento da esso e sostituire un segnaposto. Nel mio index.html ho questa riga:

<p>Questa pagina è stata aggiornata l'ultima volta alle: LASTUPDATE</p>

Nel file server.js sostituisco LASTUPDATE con la data/ora in cui il file index.html è stato aggiornato l’ultima volta. Questo dà alle persone un’idea di quando è iniziato l’aggiornamento e annoto sulla pagina che richiederà 10-15 minuti per completarsi.

Questo mi ha permesso di eseguire facilmente qualcosa sul mio server di sviluppo come test e mi sono sentito pronto a farlo in produzione.

Oops, abbiamo bisogno di https :sweat_smile:

È ora di aggiornare il server live e mostrare alle persone la mia nuova pagina temporanea!

Non è andata come previsto. Il sito live è dietro Cloudflare e richiede certificati end-to-end completi, quindi ho messo offline il forum per 15 minuti mostrando solo una pagina di errore di Cloudflare :person_facepalming:

Fortunatamente, un po’ più di copia/incolla da Stack Overflow ha aiutato. Ho cambiato il server da http a https e ho ottenuto i file cert.key e cert.pem per assicurarmi che la catena di certificati fosse intatta.

Il prossimo aggiornamento è stato un successo maggiore e le pagine temporanee sono apparse come previsto:

Mostrami solo il codice!

Ecco i due file che sto usando per questa pagina temporanea:

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"
);

Come notato sopra, puoi eseguirlo come segue:

touch index.html
node server.js 443

L’argomento 443 è la porta su cui vuoi eseguirlo, per impostazione predefinita viene eseguito sulla porta 81 in modo che io possa eseguire un curl per testare l’output, prima di farlo effettivamente durante l’aggiornamento:

curl -k https://localhost:81

A un certo punto durante l’aggiornamento di Discourse, quando sarà completato, vedrai:

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

È allora che interrompo il server Node e riavvio Discourse:

./launcher restart app

E questo è tutto. Spero che questo aiuti qualcuno!

3 Mi Piace