使用 Let's Encrypt 设置多站点配置,无需反向代理

这些说明应被视为Beta版,仅适用于熟悉标准设置的用户

但目前(2023.02.11)这些说明无效!!(请参阅 Set up Let’s Encrypt with multiple domains / redirects 了解如何更新 letsencrypt 设置以添加 fullpath 部分。我将很快更新此内容以反映这些更改。)

我几周前编写了本指南,但需要有人测试并查看它是否对其他人有效。如果您尝试了,请回复并告知我是否有效以及是否有任何不清楚的地方。

继续操作. . .

本指南大致记录了如何设置一个包含 2 个附加主机(共 3 个)的多站点设置。

它假设您有一个可用的 Discourse 官方标准安装 或 2 容器安装(https://meta.discourse.org/t/how-to-move-from-standalone-container-to-separate-web-and-data-containers/29413)。

主站点的域名

第二个站点的子域名

第三个站点的子域名

数据库密码(与 app.yml 中的 DISCOURSE_DB_PASSWORDdiscourse 相同)

为简单起见,这适用于主站点名为 =domain=,另外两个站点为 =two=.=domain= 和 =three=.=domain=。您可以使用任何名称,但为了本模板的方便,不使用不同的 short name(用于数据库名称和论坛标题)和 full hostname 会更容易一些。

app.ymlweb_only.yml 中插件后的 hooks 中添加

  before_bundle_exec:
    - file:
        path: $home/config/multisite.yml
        contents: |
         =two=:
           adapter: postgresql
           database: =two=
           pool: 25
           timeout: 5000
           host: data
           password: NThmZTNjZjZhOTczNmVj
           host_names:
             - =two=.=domain=
         =three=:
           adapter: postgresql
           database: =three=
           pool: 25
           timeout: 5000
           host: data
           password: NThmZTNjZjZhOTczNmVj
           host_names:
             - =three=.=domain=

  after_db_migrate:
    - exec: cd /var/www/discourse && sudo -E -u discourse bundle exec rake multisite:migrate

  after_ssl:
   # 告诉 letsencrypt 获取哪些附加证书
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /-d =domain= /
        to: "-d =domain= -d =two=.=domain= -d =three=.=domain="
        global: true
   # 不要将所有主机重定向回主域名
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /if \\(\\$http_host[^\\}]*\\}/m
        to: ""

添加到 app.ymldata.yml 中的 after_postgres 部分

  - exec: sudo -u postgres createdb =two= || exit 0
    - exec:
        stdin: |
          grant all privileges on database =two= to discourse;
        cmd: sudo -u postgres psql =two=
        raise_on_fail: false

    - exec: /bin/bash -c 'sudo -u postgres psql =two= <<< "alter schema public owner to discourse;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =two= <<< "create extension if not exists hstore;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =two= <<< "create extension if not exists pg_trgm;"'
    - exec: sudo -u postgres createdb =three= || exit 0
    - exec:
        stdin: |
          grant all privileges on database =three= to discourse;
        cmd: sudo -u postgres psql =three=
        raise_on_fail: false
    - exec: /bin/bash -c 'sudo -u postgres psql =three= <<< "alter schema public owner to discourse;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =three= <<< "create extension if not exists hstore;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =three= <<< "create extension if not exists pg_trgm;"'

之后,

./launcher rebuild app

或者

./launcher rebuild data
./launcher rebuild web_only
10 个赞

我刚刚尝试了一下,实际上我试了两次,因为第一次就顺利运行,没有任何问题,这让我都不敢相信了:smile: 我所做的只是复制内容,调整域名和密码,然后将其粘贴到新安装(包含 2 个容器)的相应文件中。:ok_hand:

如有任何不清楚的地方,欢迎反馈。我只对这一段稍微琢磨了一会儿:

这段内容似乎暗示必须采用 2 容器设置才能继续操作,但实际上并非如此。另外,我也不明白为什么链接指向该主题的 48 楼,而不是初始帖子。

2 个赞

谢谢!我会查看一下。这两点似乎正是那种粗心的问题,我希望你能告诉我!

编辑:谢谢!我在双容器主题中不小心复制了我的当前位置,已经修正了这一点,并将语言改为说明它适用于任何正常运行的安装。

谢谢!

2 个赞

你好!
我最初在 DigitalOcean 上安装了标准的 Discourse,然后按照这些说明配置了 Nginx,因为我希望在同一台 Droplet 上运行几个 Drupal 站点。
如果我想部署另一个 Discourse 实例,是否应该遵循上述方法?

或者,这份指南是否更合适?

谢谢!
/Sifaan

这些说明适用于不使用反向代理的情况。建议您参考 使用 Docker 配置多站点。您链接的说明可能有效,但我建议您先按照本文中的步骤操作。

2 个赞

谢谢;我注意到这样两个站点都会使用相同的 SMTP 配置:(皱眉)
有没有办法绕过这一点?
或者另一份指南是否更合适(看起来可能需要一些工作才能将现有站点接入 Docker 网络)?

另外,是否可能安装另一个代码库,比如 /var/discourse2?
(这会占用约 500MB 空间,但如果能省去我这些折腾,那也值得。)

是的。

不要使用多站点模式。

可以,但你只需要创建一个双容器安装,然后配置一个 web_only2.yml 文件。(我认为你可以使用两个 app.yml 风格的文件,但那样会不必要地运行两个 PostgreSQL 实例)。不过,我认为你确实需要两个 Redis 实例。

3 个赞

谢谢;因为我不太熟悉拆分数据和 Web 容器,所以我只是按照这些指南创建了另一个独立容器(由 certbot 生成的证书似乎也能正常工作)。不过,目前 Mailgun 配置似乎有问题——它能向 Gmail 发送激活邮件,但任何托管在我域名注册商(DreamHost)上的邮件都发送失败 :frowning:

额外的 Postgres 实例会带来多大的额外负载?
我看了您关于拆分的帖子,如果节省效果显著,我会尝试实施。

应该不会太大。只是一点内存而已。我具体不太清楚有多少。

1 个赞

最近我一直在尝试按照指南操作,但在其中几个方面遇到了困难:

  1. 我似乎找不到数据库密码(甚至不确定它在文件中是做什么用的)。
  2. 我的 app.yml 文件最初并没有包含 after_postgres 部分,因此我在 hooks 下添加了一个,以与其他部分(如 after_ssl、after_db_migrate 等)保持一致。如果这部分放错了位置,请告诉我,我完全是新手,对这类操作还不熟悉。
  3. 当我在 http://www.yamllint.com/ 上检查 YAML 文件的语法时,在将 after_postgres 部分放在 hooks 下的那一行,我收到了错误提示:(<unknown>): did not find expected key while parsing a block mapping

如果您能澄清编辑 app.yml 文件的具体步骤,我将不胜感激。

2 个赞

如果您使用的是单容器设置,可能不需要密码(之前的帖子提到过这一点)。

按您建议添加该部分应该可以生效。

我还不太确定问题出在哪里。过几天我会再仔细检查一下。

1 个赞

我想设置这个,因为我和我的朋友想在投入更多资金(可能包括单独托管等)之前测试几个不同的论坛。

我曾想过将它们放在不同的域名上,我明白这可能会带来一些混淆,因为人们将只从主SMTP地址收到电子邮件,但是,你知道单独的域名还会带来其他麻烦吗?

Discourse 为其所有商业和标准客户提供单一域名。您可以将通知电子邮件地址设置为您想要的任何地址,例如 shortname@whatevermail.com

2 个赞

我很高兴听到这个消息,谢谢!

1 个赞

您好,首先感谢您的教程。

不幸的是,我在运行单个服务器/IP上的其他 Discourse 实例时遇到了问题。
首先,我按照文档设置了一个独立站点,并且成功了。
(例如:test.john.com - 一个重定向到单个 IP 的子域)
现在当我尝试添加更多 Discourse 实例时(例如:test.joe.comtest.doe.com - 来自其他站点的其他子域)。
我尝试按照您的步骤操作,但没有成功,现在我迷失了方向。

几个问题:

  1. 这另外两个站点将如何安装?就像将 /standalone.yml 复制到 containers 目录并重命名一样?然后执行常规安装?(例如:./launcher rebuild joe
  2. 您的说明指出更改应在 app.yml 中进行,将所有代码附加在上面 - 我假设这些代码将被添加到第一个成功安装的文件(test.john.com)中?

除了 container 目录中的内容之外,我还创建了一个 config/multisite.yml,我的代码看起来像这样:

secondsite:
  adapter: postgresql
  database: b_discourse
  username: postgres
  password: postgres
  host: dbhost
  pool: 5
  timeout: 5000
  host_names:
    - test.joe.com
...
...
# 以及第三个站点的配置

不过我不确定是否还有其他需要配置的地方。

感谢您的任何回复。谢谢!

不。您按照说明将内容添加到 app.yml 中。这将在容器内创建 mutlisite.yml。将只有一个实例,并且它将适用于所有域,前提是所有域的 DNS 都指向该实例。这不是为每个域名设置多个 Discourse 容器。

据我所知,这些说明按原样是有效的。只需将这些行添加到您的 app.yml 中,它应该就可以工作了。您无需修改任何其他文件。

1 个赞

单个网站的正常设置运行完美,没有问题。
但我尝试了多种多站点组合。单个 app.yml 配置或按 web_only.yml、data.yml 等分开配置。我尝试了 使用 Docker 进行多站点配置从独立容器迁移到独立的 Web 和数据容器 中的其他技巧。

关于迁移部分,所有组合都失败了…… >>> bundle exec rake multisite:migrate

********************** 过程的最后部分**************************
2023-02-11 17:50:43.853 UTC [61] LOG:  正在关闭
162:M 11 Feb 2023 17:50:43.866 # 用户请求关闭...
162:M 11 Feb 2023 17:50:43.866 * 在退出前保存最后的 RDB 快照。
162:M 11 Feb 2023 17:50:43.881 * 数据库已保存到磁盘
162:M 11 Feb 2023 17:50:43.882 # Redis 现在已准备好退出,再见...
2023-02-11 17:50:44.007 UTC [57] LOG:  数据库系统已关闭


失败
--------------------
Pups::ExecError: cd /var/www/discourse &amp;&amp; sudo -E -u discourse bundle exec rake multisite:migrate failed with return #&lt;Process::Status: pid 582 exit 1&gt;
失败位置:/usr/local/lib/ruby/gems/3.1.0/gems/pups-1.1.1/lib/pups/exec_command.rb:117:in `spawn'
exec failed with the params "cd /var/www/discourse &amp;&amp; sudo -E -u discourse bundle exec rake multisite:migrate"
bootstrap failed with exit code 1
**引导失败** 请向上滚动并查找更早的错误消息,可能不止一个。
./discourse-doctor 可能有助于诊断问题。

我检查了在失败之前创建了什么,又没有创建什么。
子域数据库已创建,但迁移失败。当我检查 overlay2 文件夹或任何其他地方时,子域 nginx 配置或 multisite.yml 未能创建。

./launcher bootstrap, destroy, start, stop, rebuild 或 fresh setup 多次……尝试了所有命令但什么都没发生…… :slight_smile:

此教程对于 v3.1.0.beta 2 是否仍然有效,或者我可能遗漏了什么?
有什么想法吗?

1 个赞

不适用。Let’s Encrypt 在某个时候发生了一些变化。我将让你仔细看看容器内需要更改哪些内容来处理多个域。

1 个赞

我正在使用此方法,效果很好。我目前没有启用 HTTPS,因此无法评论 Let’s Encrypt 的困难。

我多年来一直在我暂存服务器上使用此设置。但是,自从更新到 3.5.0.beta5-dev 后,每当我输入子域时,我都会被重定向到主站点。

我一直很高兴不必处理所有认证方面的事情。但现在我非常困惑,有什么工具可以调试正在发生的事情吗?

1 个赞