# 为 Discourse 重建或启动时添加一个离线页面显示

**URL:** <https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238>\
**Category:** Sysadmins\
**Tags:** configuring, how-to, advanced-setup\
**Created:** [2016年六月4日 08:41 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238 "2016-06-04T08:41:48Z")\
**Posts on this page:** 20\
**Page:** 6

<div class="post-metadata">

**Author:** ![amotl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/amotl/32/109873_2.png) [@amotl](https://meta.discourse.org/u/amotl)\
**Post date:** [2019年十二月11日 03:08 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/121 "2019-12-11T03:08:42Z")

</div>

> [@jomaxro](#):
>
> 在使用 Docker Manager（`/admin/upgrade`）进行升级时，Discourse 绝不应该离线。通常它也会对你离线吗？

也许我们只是实现了离线页面，因为我们在多次遭遇 [1,2,3] 这类问题后，开始采用“停止容器、git pull、launcher rebuild

---

<div class="post-metadata">

**Author:** ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)\
**Post date:** [2020年七月26日 03:19 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/122 "2020-07-26T03:19:13Z")

</div>

> [@fefrei](#):
>
> **本指南面向高级用户，即那些已经在 Docker 容器外部使用 nginx 的用户。**

这有点令人困惑，因为接下来的内容正是关于在容器外部安装和配置 nginx 的指南。

无论如何，今天我意识到这种外部 nginx 配置的一个额外好处：如果你习惯于看到注册或登录 IP 地址显示为 127.0.0.1 或你的 Docker 地址（可能以 172. 开头），那可能是因为 IPv6 流量被转发到容器时没有携带其 IPv6 地址，而 IPv4 则不同。通过这种配置，你现在将看到正确的 IPv6 地址，而不是本地地址。

换句话说，这种配置对于在日益普及 IPv6 的互联网上正确使用某些管理工具来说，本质上是 **必需** 的。（在美国，这包括大量的移动流量。）

---

<div class="post-metadata">

**Author:** ![paulrudy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/paulrudy/32/259901_2.png) [@paulrudy](https://meta.discourse.org/u/paulrudy)\
**Post date:** [2020年九月25日 15:50 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/123 "2020-09-25T15:50:23Z")

</div>

感谢这份非常实用的指南！我有几点补充：

我认为 `sudo apt-get install letsencrypt` 已被 `sudo apt-get install certbot` 取代。运行前者时，我会收到提示：`注意：正在选择 'certbot' 而非 'letsencrypt'`。

一位朋友注意到，在 Facebook 上分享该网站时，预览显示的是“301 永久移动”。

编辑：我最初将端口 80 服务器块中的 `location /` 部分替换为端口 443 服务器块中的 `location /` 部分。但我认为这是多余的。相反，我直接删除了作为重定向块的端口 80 服务器块，并在主服务器块的相应部分添加了：

```plaintext
    listen [::]:80;
    listen 80;

```

我还在 Discourse 设置中启用了 HTTPS 重定向（不确定这是否必要）。

这解决了 Facebook 分享的问题，而且看起来常规的 HTTP 请求确实已被重定向到 HTTPS。如果有其他或更好的方法，请告诉我。

---

<div class="post-metadata">

**Author:** ![datvnn](https://avatars.discourse-cdn.com/v4/letter/d/ba9def/32.png) [@datvnn](https://meta.discourse.org/u/datvnn)\
**Post date:** [2020年十一月1日 15:24 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/124 "2020-11-01T15:24:16Z")

</div>

感谢这个教程，非常棒。现在我的 502 页面看起来好多了。  
在我的实际场景中，我需要将 nginx 配置添加到 `/etc/nginx/sites-enabled/discourse.conf` 文件中。  
在 nginx 运行 WordPress 之后，我已经成功安装了 Discourse。

---

<div class="post-metadata">

**Author:** ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)\
**Post date:** [2021年四月30日 01:50 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/125 "2021-04-30T01:50:37Z")

</div>

我遇到了一个问题：按照该指南安装后，由于未重启 nginx，它并不知道证书已更新。我的解决方案如下：

```plaintext
systemctl edit certbot

```

然后添加以下两行：

```plaintext
[Service]
ExecStartPost=/bin/systemctl reload nginx

```

或者，在系统中我使用了一个独立的 `mail-receiver` 容器，该容器也共享系统的证书：

```plaintext
[Service]
ExecStartPost=/bin/systemctl reload nginx
ExecStartPost=/bin/sh -c 'cd /var/discourse && ./launcher restart mail-receiver'

```

---

<div class="post-metadata">

**Author:** ![Blechpirat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blechpirat/32/221370_2.png) [@Blechpirat](https://meta.discourse.org/u/Blechpirat)\
**Post date:** [2021年六月10日 08:57 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/126 "2021-06-10T08:57:49Z")

</div>

感谢这个教程，对我来说效果很好。

我只是想请教一下：如果像 Googlebot 这样的搜索引擎爬虫看到了这个错误页面，它会知道这是一个临时页面吗？或者我们需要发送某种错误代码，让它意识到这只是临时的变更？

我可不希望因为一个更花哨的错误页面，导致 Google 删除了我论坛的所有索引内容。

---

<div class="post-metadata">

**Author:** ![ashs](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ashs/32/223132_2.png) [@ashs](https://meta.discourse.org/u/ashs)\
**Post date:** [2021年六月10日 09:41 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/127 "2021-06-10T09:41:48Z")

</div>

Google 应将 500/502 错误视为“稍后重试”的信号。只要您的网站没有过于频繁地重建，就不会有问题。

我的论坛一直通过 nginx 运行，这并未对排名产生负面影响。

---

<div class="post-metadata">

**Author:** ![Blechpirat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blechpirat/32/221370_2.png) [@Blechpirat](https://meta.discourse.org/u/Blechpirat)\
**Post date:** [2021年六月10日 10:02 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/128 "2021-06-10T10:02:47Z")

</div>

好的，我不确定是否仍在发送 502 错误。

---

<div class="post-metadata">

**Author:** ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)\
**Post date:** [2021年七月7日 11:18 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/129 "2021-07-07T11:18:44Z")

</div>

它仍在发送。你可以通过以下方式确认：

根据 [nginx 文档](http://nginx.org/en/docs/http/ngx_http_core_module.html)：

> 语法：`error_page code` … [`=` [ `response`]] `uri` ;

以下是配置中的代码片段：

```plaintext
error_page 502 =502 /errorpages/discourse_offline.html;

```

这意味着“当遇到（或生成）502 Bad Gateway 响应码时，使用 502 Bad Gateway 响应码发送 `/errorpages/discourse_offline.html` 文件的内容。`=` 用于指定要发送的 HTTP 响应码。

一切正常！

我同意 @ashs 的观点：每月偶尔出现一两次、持续一分钟以内的 502 错误不会影响搜索。我经常在谷歌搜索结果中看到最新的帖子。

---

<div class="post-metadata">

**Author:** ![EddieT](https://avatars.discourse-cdn.com/v4/letter/e/f4b2a3/32.png) [@EddieT](https://meta.discourse.org/u/EddieT)\
**Post date:** [2021年八月3日 20:51 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/130 "2021-08-03T20:51:21Z")

</div>

执行此操作后，我仍然收到来自 Cloudflare 的 502 网关错误…

---

<div class="post-metadata">

**Author:** ![fefrei](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fefrei/32/119538_2.png) [@fefrei](https://meta.discourse.org/u/fefrei)\
**Post date:** [2021年八月4日 08:29 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/131 "2021-08-04T08:29:12Z")

</div>

502 错误通常表示 Nginx 未启动，可能是由于配置错误。运行 `nginx -t` 可以检查配置文件是否正常。如果没有报错，请运行 `systemctl status nginx.service` 查看 Nginx 服务的状态。

---

<div class="post-metadata">

**Author:** ![EddieT](https://avatars.discourse-cdn.com/v4/letter/e/f4b2a3/32.png) [@EddieT](https://meta.discourse.org/u/EddieT)\
**Post date:** [2021年八月4日 13:26 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/132 "2021-08-04T13:26:54Z")

</div>

我成功配置了 Nginx，但随后只遇到 404 错误，尽管我已将所有文件放置在了正确的位置，理应能够正常显示。

---

<div class="post-metadata">

**Author:** ![bobbysmith](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@bobbysmith](https://meta.discourse.org/u/bobbysmith)\
**Post date:** [2021年八月4日 20:42 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/133 "2021-08-04T20:42:15Z")

</div>

我的问题与主题标题直接相关，但与本文讨论的方法无关，因此希望将其保留在此讨论中是可以的。

我搭建了一个非常简单的环境来解决这个问题，并有一个具体问题。

我在 DigitalOcean 上创建了一个独立的 Droplet，并通过市场安装了一个 LAMP 服务器。随后，我上传了一个包含一些图片的基本 HTML 页面，用于提示服务器正在维护。之后，我可以根据需要在我的常规 Discourse 服务器和维护服务器之间浮动 IP 地址。

我的问题是：为了让“维护”服务器正确加载，我最终需要通过 certbot 为该服务器获取一个证书（除了我已经为主要的 Discourse 实例拥有的证书之外）。换句话说，同一个域名在不同服务器上拥有两个证书。虽然这确实可行，但我一直担心这是否会在未来引发问题。我在网上查阅的资料表明这样做是可以的，但我还是想确认是否有人有过这方面的直接经验。

---

<div class="post-metadata">

**Author:** ![fefrei](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fefrei/32/119538_2.png) [@fefrei](https://meta.discourse.org/u/fefrei)\
**Post date:** [2021年八月5日 07:24 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/134 "2021-08-05T07:24:04Z")

</div>

这样做完全有效。不过，具体取决于您执行的验证方式，证书续期可能无法正常工作——例如，如果您的“维护”服务器使用的是基于 HTTP 的验证，那么在域名未指向该服务器时验证将会失败，这很可能违背了初衷。或许更合理的做法是，让维护服务器定期从主服务器复制最新的证书，而不是直接向 Let’s Encrypt 申请新证书。

---

<div class="post-metadata">

**Author:** ![bobbysmith](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@bobbysmith](https://meta.discourse.org/u/bobbysmith)\
**Post date:** [2021年八月5日 18:49 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/135 "2021-08-05T18:49:18Z")

</div>

感谢你的回复和建议，Felix。

我得承认，我完全不清楚我的服务器是否使用了基于 HTTP 的验证（我只是通过那个出色的 Certbot 完成了所有操作），但你的担忧完全合乎逻辑。我稍微查找了一下，但没找到任何关于如何按你建议的那样复制证书的资源。另外，我猜我可能需要设置某种 cron 任务。如果你还有其他建议，那就太好了。否则，再次感谢你的帮助。

---

<div class="post-metadata">

**Author:** ![fefrei](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fefrei/32/119538_2.png) [@fefrei](https://meta.discourse.org/u/fefrei)\
**Post date:** [2021年八月5日 19:05 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/136 "2021-08-05T19:05:18Z")

</div>

要从服务器直接复制文件，`scp` 或 `rsync` 是很好的工具——[这个](https://tldr.ostera.io/scp) 链接可以作为入门参考。

我的建议确实是设置一个定时任务（cron job），定期将证书从主服务器复制到维护服务器 🙂

顺便解释一下基于 HTTP 的验证背景：为了确认域名确实属于您，Let’s Encrypt 会从您的服务器请求一个特定文件，并期望得到特定的响应。Certbot 可以自动处理这一过程（临时配置您的服务器以在验证请求时返回该文件），但前提是请求必须真正到达您的服务器。如果您的 DNS 未指向您的服务器，或者您已将 IP 地址迁移到其他位置，请求就会发往错误的服务器，Let’s Encrypt 将无法收到预期的响应，从而拒绝签发证书。

---

<div class="post-metadata">

**Author:** ![bobbysmith](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@bobbysmith](https://meta.discourse.org/u/bobbysmith)\
**Post date:** [2021年八月6日 19:50 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/137 "2021-08-06T19:50:02Z")

</div>

我会进一步调查此事。再次感谢提供的链接和帮助。

---

<div class="post-metadata">

**Author:** ![haydenjames](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/haydenjames/32/255678_2.png) [@haydenjames](https://meta.discourse.org/u/haydenjames)\
**Post date:** [2022年四月4日 20:28 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/138 "2022-04-04T20:28:17Z")

</div>

> [@amotl](#):
>
> _管理员 » 备份 » 启用只读_

…这是否可以在无需手动设置的情况下解决？谢谢。

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2022年四月4日 20:50 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/139 "2022-04-04T20:50:19Z")

</div>

如果您想在网站重建期间创建一个“正在建设中”页面，您需要执行上述繁琐的步骤。我建议切换到双容器安装，这种安装在维护上会有些麻烦（您需要知道何时重建数据容器），但新容器启动时只有大约 30 秒的停机时间，不过目前需要相当多的内存（2GB 可能不够，但我不完全确定）。

---

<div class="post-metadata">

**Author:** ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)\
**Post date:** [2022年九月25日 23:28 UTC](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238/140 "2022-09-25T23:28:41Z")

</div>

请注意，`letsencrypt` 包现在通常称为 `certbot`。

[上一頁](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238.md?page=5)

[下一頁](https://meta.discourse.org/t/add-an-offline-page-to-display-when-discourse-is-rebuilding-or-starting-up/45238.md?page=7)
