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

Maybe we just implemented the offline page because we started using the upgrade procedure »stop container, git pull, launcher rebuild« after being hit by things like [1,2,3] for a few times actually.

Maybe something changed on the robustness of killing PostgreSQL if it wouldn’t shutdown in time to run through the upgrade process smoothly.

Either way, the online upgrade (again) worked well for us when giving it another shot right now. So, nevermind and sorry for the noise.

[1] Discourse stuck on "Currently Upgrading" - #15 by amotl
[2] Upgrade failed due to unclean database shutdown
[3] https://meta.discourse.org/t/upgrade-failed-due-to-unclean-database-shutdown-ii/103268

3 个赞

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

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

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

4 个赞

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

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

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

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

    listen [::]:80;
    listen 80;

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

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

2 个赞

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

2 个赞

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

systemctl edit certbot

然后添加以下两行:

[Service]
ExecStartPost=/bin/systemctl reload nginx

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

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

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

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

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

1 个赞

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

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

5 个赞

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

1 个赞

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

根据 nginx 文档

语法:error_page code … [ = [ response ]] uri ;

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

error_page 502 =502 /errorpages/discourse_offline.html;

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

一切正常!

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

2 个赞

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

1 个赞

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

5 个赞

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

1 个赞

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

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

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

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

2 个赞

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

3 个赞

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

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

1 个赞

要从服务器直接复制文件,scprsync 是很好的工具——这个 链接可以作为入门参考。

我的建议确实是设置一个定时任务(cron job),定期将证书从主服务器复制到维护服务器 :slight_smile:

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

3 个赞

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

1 个赞

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

1 个赞

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

4 个赞

请注意,letsencrypt 包现在通常称为 certbot

1 个赞