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

These instructions should be considered beta and for those familiar with a standard setup

But right now (2023.02.11) these instructions do not work!! (See Set up Let’s Encrypt with multiple domains / redirects for how to update the letsencrypt setting to add the fullpath part. I’ll update this to reflect those changes Real Soon Now.)

I developed this howto a couple weeks ago but need someone to test and see if this works for someone else. Please reply if you try and let me know whether it works and if anything is unclear.

And on with the show. . .

This howto documents broadly how to set up a multisite setup with 2 additional hosts (3 total).

It assumes that you have a working Discourse official Standard Installation or 2-container installation (Move from standalone container to separate web and data containers).

Domain name for primary site

subdomain for the 2nd site

Suddomain for the 3rd site

Database password (same as DISCOURSE_DB_PASSWORD) or discourse in app.yml

For the sake of simplicity, this is for a main site called =domain=, with two additional sites =two=.=domain= and =three=.=domain=. You can use whatever names you want, but for the sake of this template, not having a different short name (for the database name and title for the sub-forum) and full hostname is a bit easier.

add in hooks after the plugins in app.yml or web_only.yml

  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:
   # tell letsencrypt what additional certs to get
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /-d =domain= /
        to: "-d =domain= -d =two=.=domain= -d =three=.=domain="
        global: true
   # do not redirect all hosts back to the main domain name
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /if \(\$http_host[^\}]*\}/m
        to: ""

Add to the after_postgres section in app.yml or data.yml

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

After that,

./launcher rebuild app

or

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

I just tried it out, in fact I tried it twice because I couldn’t believe it just worked without any problems the first time already :smile: All I did was copying, adjusting the domains and password and then pasting into the respective files of a fresh installation with 2 containers. :ok_hand:

Regards feedback whether anything is unclear, I only had to mull a bit over this paragraph:

It seems to suggest a 2-container setup is necessary to follow along, but then it isn’t. And I didn’t understand why it links to post 48 of the topic, rather than the initial post.

1 个赞

Thanks! I’ll take a look. Those both seem like the kind of careless things I was hoping you’d let me know about!

EDIT: Thanks! I’d carelessly copied my current location in the 2-container topic, so I fixed that, and changed the language to say that it’ll work with any working installation.

Thanks!

2 个赞

Hi
I started with a standard Discourse install (at DigitalOcean), then setup nginx (using these instructions) because I wanted a couple of Drupal sites on the same droplet
If I want to have another instance of Discourse should I follow the above?

Or would this guide be better?

Thanks!
/Sifaan

These instructions are for not using a reverse proxy. I’d recommend that you follow Multisite configuration with Docker. The instructions that you linked might work, but I’d recommend that you first follow what’s here.

1 个赞

Thanks; I notice that with that both sites would use the same SMTP config :frowning:
is there a way to bypass that?
or would the other guide be better (looks like it might require some work to put the existing site on the docker network)

alternately, is it possible to install another codebase, say /var/discourse2 ?
(it will cost me ~500MB but worth it if it saves me the brain damage)

Yes.

Don’t use multisite.

Yes, but you just need to create a 2-container installation and then have a web_only2.yml. (I think that you can have 2 app.yml-style files, but then you’re needlessly running two postgres instances). I think, though, that you do need two redis instances.

3 个赞

Thanks; because I am not too familiar with splitting the data and web container I just created another standalone container following these guidelines (and certificates created by certbot seem to be working). However currently there seems to be an issue with mailgun config - it sends activation emails to gmail but anything mail hosted at my registrar (dreamhost) is failing :frowning:

How much of a extra load would the extra Postgres instance causing?
I looked at your post about splitting and will try it if the savings were significant.

Probably not that much. Just a bit of RAM. I have little idea how much.

1 个赞

Recently I’ve been giving this a try, but I’m having trouble with a couple of things in the guide:

  1. I can’t seem to find the Database password (or what it is even used for in the file)
  2. My app.yml file did not originally contain an after_postgres section, so I added one under hooks to match the others (after_ssl, after_db_migrate, etc.). If this is placed in the wrong section, please let me know, I’m completely new to working with this type of stuff.
  3. When I check the syntax of the YAML file on http://www.yamllint.com/ I get (<unknown>): did not find expected key while parsing a block mapping on the line where I put the after_postgres section under the hooks section.

If you could clarify the steps for editing the app.yml file, that would be greatly appreciated.

2 个赞

Maybe you don’t need a password if you’re using a single container setup (an earlier post suggests that).

Adding the section as you suggest should work.

I can’t quite the what might be wrong. I’ll try to take a closer look on a couple of days.

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 后,每当我输入子域时,我都会被重定向到主站点。

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