Configuração de Multisite com Let's Encrypt sem Reverse Proxy

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 curtidas

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 curtida

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 curtidas

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 curtida

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 curtidas

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 curtida

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 curtidas

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 curtida

Estou pensando em configurar isso, pois meu amigo e eu queremos testar alguns fóruns diferentes antes de decidirmos se queremos investir mais neles, possivelmente tendo hospedagem separada e tal.

Eu estava pensando em tê-los em domínios diferentes. Entendo que isso pode causar um pouco de confusão, pois as pessoas receberão e-mails apenas do endereço SMTP principal, no entanto, você sabe se domínios separados criariam outros problemas?

O Discourse tem um único domínio para todos os seus clientes empresariais e padrão. Você pode definir o endereço de e-mail de notificação como desejar, como nomecurto@qualquermemail.com.

2 curtidas

Fico muito feliz em saber disso, obrigado!

1 curtida

Olá, primeiramente obrigado pelo tutorial.

Infelizmente, tenho um problema ao executar múltiplos sites do Discourse em um único servidor/IP.
Primeiro, segui a documentação para configurar um site independente e foi bem-sucedido.
(por exemplo, test.john.com - um subdomínio redirecionado para o IP único)
Agora, quando tentei adicionar mais sites do Discourse (por exemplo, test.joe.com e test.doe.com - outros subdomínios de outros sites).
Tentei seguir seus passos, mas não obtive sucesso e agora estou perdido.

Algumas perguntas:

  1. Como esses dois sites adicionais serão instalados? Como copiar o /standalone.yml para o diretório containers e renomeá-lo? E apenas fazer a instalação regular? (por exemplo, ./launcher rebuild joe)
  2. Sua instrução afirma que as alterações devem ser feitas no app.yml, anexando todo o código acima - que presumo que será adicionado ao arquivo do primeiro site instalado com sucesso (test.john.com)?

Além daqueles no diretório container, criei um config/multisite.yml e este é o meu código:

secondsite:
  adapter: postgresql
  database: b_discourse
  username: postgres
  password: postgres
  host: dbhost
  pool: 5
  timeout: 5000
  host_names:
    - test.joe.com
...
...
# e a configuração do terceiro site

No entanto, não tenho certeza se há outras coisas que preciso configurar.

Agradeço qualquer resposta. Obrigado!

Não. Você adiciona as coisas ao app.yml conforme descrito. Isso criará o mutlisite.yml dentro do contêiner. Haverá uma única instância e funcionará para todos os domínios, dado que o DNS de todos eles aponta para lá. Isso não é para ter vários contêineres Discourse, um para cada nome de domínio.

Pelo que me lembro, essas instruções funcionaram como escritas. Basta adicionar as linhas ao seu app.yml e deve funcionar. Você não precisa mexer em nenhum outro arquivo.

1 curtida

Configuração de site único normal funciona perfeitamente. Sem problemas.
Mas tentei muitas combinações para multissite. Configuração de app.yml única ou separada por web_only.yml, data.yml etc… Tentei outras dicas em Configuração de multissite com Docker ou Mover de contêiner autônomo para contêineres web e de dados separados.

Quanto à parte de migração, todas as combinações sempre falharam… >> bundle exec rake multisite:migrate

********************** última parte do processo**************************
2023-02-11 17:50:43.853 UTC [61] LOG: desligando
162:M 11 Fev 2023 17:50:43.866 # Usuário solicitou desligamento...
162:M 11 Fev 2023 17:50:43.866 * Salvando o snapshot RDB final antes de sair.
162:M 11 Fev 2023 17:50:43.881 * DB salvo em disco
162:M 11 Fev 2023 17:50:43.882 # Redis está pronto para sair, tchau tchau...
2023-02-11 17:50:44.007 UTC [57] LOG: sistema de banco de dados está desligado


FALHOU
--------------------
Pups::ExecError: cd /var/www/discourse &amp;&amp; sudo -E -u discourse bundle exec rake multisite:migrate falhou com retorno #&lt;Process::Status: pid 582 exit 1&gt;
Localização da falha: /usr/local/lib/ruby/gems/3.1.0/gems/pups-1.1.1/lib/pups/exec_command.rb:117:in `spawn'
exec falhou com os parâmetros "cd /var/www/discourse &amp;&amp; sudo -E -u discourse bundle exec rake multisite:migrate"
bootstrap falhou com código de saída 1
** FALHA AO INICIALIZAR ** por favor, role para cima e procure por mensagens de erro anteriores, pode haver mais de uma.
./discourse-doctor pode ajudar a diagnosticar o problema.

Verifiquei o que foi criado e o que não foi criado até a falha.
Bancos de dados de subdomínios são criados, mas a migração falhou. Configurações nginx de subdomínios ou multisite.yml não puderam ser criadas quando verifiquei as pastas overlay2 ou em qualquer lugar.

./launcher bootstrap,destroy,start,stop,rebuild ou configuração inicial muitas vezes … Tentei todos os comandos, mas nada aconteceu… :slight_smile:

Este tutorial ainda é válido para v3.1.0.beta 2 ou o que eu posso estar perdendo?
Alguma ideia, por favor?

1 curtida

Não. Algo sobre o Let’s Encrypt mudou em algum momento. Vou pedir para você dar uma olhada mais de perto em tudo o que precisa ser alterado dentro do contêiner para lidar com vários domínios.

1 curtida

Estou usando este método e ele funciona bem. Atualmente não tenho https ativado, então não posso comentar sobre as dificuldades do Let’s Encrypt.

Tenho usado essa configuração por anos com meus servidores de staging. No entanto, desde a atualização para 3.5.0.beta5-dev, sou redirecionado para o site principal sempre que insiro um subdomínio.

Fiquei tão feliz por não ter que lidar com toda a questão de certificação. Mas agora estou bem perdido, existem ferramentas para depurar o que está acontecendo?