Configuration Multisite avec Let's Encrypt et sans 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 « J'aime »

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 « J'aime »

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 « J'aime »

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 « J'aime »

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 « J'aime »

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 « J'aime »

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 « J'aime »

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 « J'aime »

Je pense à mettre cela en place, car mon ami et moi voulons tester quelques forums différents avant de décider si nous voulons investir davantage dans ceux-ci, en ayant éventuellement un hébergement séparé et ainsi de suite.

Je pensais les avoir sur des domaines différents, je comprends que cela puisse apporter une petite confusion car les gens recevront les e-mails de la seule adresse SMTP principale, cependant, savez-vous si des domaines séparés créeraient d’autres problèmes?

Discourse a un seul domaine pour tous ses clients professionnels et standard. Vous pouvez définir l’adresse e-mail de notification comme vous le souhaitez, par exemple shortname@whatevermail.com.

2 « J'aime »

Je suis vraiment content d’entendre cela, merci !

1 « J'aime »

Salut, tout d’abord merci pour le tutoriel.

Malheureusement, j’ai un problème pour exécuter plusieurs instances de Discourse sur un seul serveur/IP.
J’ai d’abord suivi la documentation pour configurer un site autonome et cela a réussi.
(par exemple, test.john.com - un sous-domaine redirigeant vers l’IP unique)
Maintenant, lorsque j’ai essayé d’ajouter d’autres instances de Discourse (par exemple, test.joe.com et test.doe.com - d’autres sous-domaines d’autres sites).
J’ai essayé de suivre vos étapes, mais cela n’a pas abouti et maintenant je suis perdu.

Quelques questions :

  1. Comment ces deux autres sites seront-ils installés ? Comme copier le /standalone.yml dans le répertoire containers et le renommer ? Et ensuite faire l’installation habituelle ? (par exemple, ./launcher rebuild joe)
  2. Votre instruction indique que les modifications doivent être apportées dans le fichier app.yml, en ajoutant tout le code ci-dessus - ce qui, je suppose, sera ajouté dans le fichier du premier site installé avec succès (test.john.com) ?

Outre ceux du répertoire container, j’ai créé un fichier config/multisite.yml et voici à quoi ressemble mon code :

secondsite:
  adapter: postgresql
  database: b_discourse
  username: postgres
  password: postgres
  host: dbhost
  pool: 5
  timeout: 5000
  host_names:
    - test.joe.com
...
...
# et la configuration du troisième site

Je ne suis cependant pas sûr s’il y a d’autres éléments que je dois configurer.

J’apprécierais toute réponse. Merci !

Non. Vous ajoutez les éléments à app.yml comme décrit. Cela créera mutlisite.yml à l’intérieur du conteneur. Il y aura une seule instance et cela fonctionnera pour tous les domaines, étant donné que le DNS de tous les domaines y pointe. Ceci n’est pas destiné à avoir plusieurs conteneurs Discourse, un pour chaque nom de domaine.

D’après mes dernières vérifications, ces instructions fonctionnaient telles qu’elles étaient écrites. Ajoutez simplement les lignes à votre app.yml et cela devrait fonctionner. Vous n’avez pas besoin de toucher à d’autres fichiers.

1 « J'aime »

La configuration d’un seul site Web fonctionne parfaitement. Aucun problème.
Mais j’ai essayé de nombreuses combinaisons pour le multisite. Configuration unique de app.yml ou séparée par web_only.yml, data.yml etc… J’ai essayé d’autres astuces sur Configuration multisite avec Docker ou Passage d’un conteneur autonome à des conteneurs web et de données séparés.

En ce qui concerne la partie migration, toutes les combinaisons ont toujours échoué… >> bundle exec rake multisite:migrate

********************** dernière partie du processus**************************
2023-02-11 17:50:43.853 UTC [61] LOG: arrêt en cours
162:M 11 Fév 2023 17:50:43.866 # Arrêt demandé par l'utilisateur...
162:M 11 Fév 2023 17:50:43.866 * Sauvegarde du dernier instantané RDB avant la sortie.
162:M 11 Fév 2023 17:50:43.881 * DB sauvegardée sur disque
162:M 11 Fév 2023 17:50:43.882 # Redis est maintenant prêt à quitter, au revoir...
2023-02-11 17:50:44.007 UTC [57] LOG: le système de base de données est arrêté


ÉCHEC
--------------------
Pups::ExecError: cd /var/www/discourse &amp;&amp; sudo -E -u discourse bundle exec rake multisite:migrate a échoué avec le retour #&lt;Process::Status: pid 582 exit 1&gt;
Emplacement de l'échec : /usr/local/lib/ruby/gems/3.1.0/gems/pups-1.1.1/lib/pups/exec_command.rb:117:in `spawn'
exec a échoué avec les paramètres "cd /var/www/discourse &amp;&amp; sudo -E -u discourse bundle exec rake multisite:migrate"
bootstrap a échoué avec le code de sortie 1
** ÉCHEC DU BOOTSTRAP ** veuillez faire défiler vers le haut et rechercher les messages d'erreur précédents, il peut y en avoir plus d'un.
./discourse-doctor peut aider à diagnostiquer le problème.

J’ai vérifié ce qui a été créé et ce qui n’a pas été créé jusqu’à l’échec.
Les bases de données des sous-domaines sont créées mais la migration a échoué. Les configurations nginx des sous-domaines ou multisite.yml n’ont pas pu être créées lorsque j’ai vérifié les dossiers overlay2 ou n’importe où.

./launcher bootstrap,destroy,start,stop,rebuild ou nouvelle configuration de nombreuses fois… J’ai essayé toutes les commandes mais rien ne s’est passé… :slight_smile:

Ce tutoriel est-il toujours valide pour v3.1.0.beta 2 ou qu’est-ce que je pourrais manquer ?
Une idée, s’il vous plaît ?

1 « J'aime »

Non. Quelque chose concernant Let’s Encrypt a changé à un moment donné. Je vais vous demander d’examiner de plus près tout ce qui doit être modifié dans le conteneur pour gérer plusieurs domaines.

1 « J'aime »

J’utilise cette méthode et elle fonctionne bien. Je n’ai pas https activé actuellement, donc je ne peux pas commenter les difficultés de Let’s Encrypt.

J’utilise cette configuration depuis des années avec mes serveurs de staging. Cependant, depuis la mise à jour vers la version 3.5.0.beta5-dev, je suis maintenant redirigé vers le site principal chaque fois que j’entre un sous-domaine.

J’étais tellement heureux de ne pas avoir à me plonger dans tout ce qui concerne les certifications. Mais maintenant, je suis assez perdu, existe-t-il des outils pour déboguer ce qui se passe ?