# 分享：在升级过程中设置占位页面的简易方法

**URL:** <https://meta.discourse.org/t/sharing-a-rudimentary-way-to-set-up-a-holding-page-while-upgrading/359276>\
**Category:** General\
**Created:** [2025年三月28日 12:33 UTC](https://meta.discourse.org/t/sharing-a-rudimentary-way-to-set-up-a-holding-page-while-upgrading/359276 "2025-03-28T12:33:49Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![cultiv](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cultiv/32/483312_2.png) [@cultiv](https://meta.discourse.org/u/cultiv)\
**Post date:** [2025年三月28日 12:33 UTC](https://meta.discourse.org/t/sharing-a-rudimentary-way-to-set-up-a-holding-page-while-upgrading/359276/1 "2025-03-28T12:33:49Z")

</div>

_ **注意：** 不确定放在哪里，如果我遗漏了什么，请随时移至更合适的位置。_

只是想分享一下我过去一周为在 Discourse 升级时快速搭建一个临时页面而设计的一种快速、简陋的方法。我阅读了所有现有的指南，但我对 nginx 和双容器设置一无所知，这看起来非常令人生畏。

tl;dr; 我做了一个东西，代码在下面。👇

## Node.js 来救援

所以我想：最快的方法是什么，只是启动一个超级小的单页 Web 服务器？然后我才想起 Node.js 已经安装了，我是否可以只用它就搞定？

快速搜索并从 Stackoverflow 复制粘贴后，我得到了一个监听端口 80 的小东西！

这个过程非常手动，但我认为还可以，我需要在升级运行时监控日志，所以我等待看到信号：

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

```

这时，我会有另一个打开的 SSH 会话，在那里我快速运行：

```plaintext
touch index.html
node server.js 80

```

我 `touch` `index.html` 文件，以便从中读取更新日期，并替换一个占位符。在我的 `index.html` 中，我有这一行：

```html
<p>此页面最后更新时间为：LASTUPDATE</p>

```

在 server.js 文件中，我将 `LASTUPDATE` 替换为 `index.html` 文件最后更新的日期/时间。这只是为了让人们了解升级何时开始，并且我在页面上注明通常需要 10-15 分钟才能完成。

这让我可以在开发服务器上轻松运行一些东西进行测试，并感觉准备好在生产环境上进行了。

### 哎呀，我们需要 https 😅

是时候升级生产服务器并向人们展示我的新快速临时页面了！

事与愿违。生产站点位于 Cloudflare 后面，需要提供完整的端到端证书，所以我将论坛停了 15 分钟，只显示了一个 Cloudflare 错误页面 🤦

幸运的是，从 Stack Overflow 复制粘贴了一些内容有所帮助。我将服务器从 http 切换到 https，并获取了 `cert.key` 和 `cert.pem` 文件，以确保证书链完整。

下一次升级取得了更大的成功，临时页面按设计显示了出来：

 ![图片是一个“我们马上回来”的消息，表明由于更新而暂时服务中断，通常需要 10-15 分钟，并提供了最后更新时间。（由 AI 标注）](https://global.discourse-cdn.com/meta/original/4X/f/a/5/fa5f0573f3f75cd22d1491563931d54a23f9b6dd.png)

### 只给我看代码！

这是我用于此临时页面的两个文件：

`index.html`

```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`

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

```

如上所述，您可以这样运行它：

```plaintext
touch index.html
node server.js 443

```

`443` 参数是要运行的端口，默认情况下它运行在端口 81 上，这样我就可以在实际在升级期间执行此操作之前，使用 `curl` 测试输出：

```plaintext
curl -k https://localhost:81

```

在 Discourse 升级过程中的某个时候，当它完成时，您会看到：

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

```

那时我将终止 Node 服务器并重新启动 Discourse：

```plaintext
./launcher restart app

```

就是这样。希望这对某人有帮助！

---

_[View the full topic](https://meta.discourse.org/t/sharing-a-rudimentary-way-to-set-up-a-holding-page-while-upgrading/359276)._
