Setting up Let’s Encrypt with Multiple Domains


(Brahn) #1

See the excellent topic Setting up Let’s Encrypt as your first step!

In addition to that setup, the following is my technique for registering multiple domains (very handy with a multisite setup).

Step 1 - letsencrypt

It’s pretty simple really, add something like the following to your app.yml hooks section:

  after_ssl:
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /-k 4096 -w \/var\/www\/discourse\/public/
        to: |
          -d www.main-domain.com -d second-domain.com -d www.second-domain.com -d other-domain.com -d www.other-domain.com -k 4096 -w /var/www/discourse/public

    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /-k 4096 --force -w \/var\/www\/discourse\/public/
        to: |
          -d www.main-domain.com -d second-domain.com -d www.second-domain.com -d other-domain.com -d www.other-domain.com -k 4096 --force -w /var/www/discourse/public

The RegEx is perhaps overly specific but you get the idea.

This replaces the two occurrences where acme.sh is called to issue a cert to the DISCOURSE_HOSTNAME

So this:

LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --issue -d main-domain.com -k 4096 -w /var/www/discourse/public

Becomes this:

LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --issue -d main-domain.com -d www.main-domain.com -d second-domain.com -d www.second-domain.com -d other-domain.com -d www.other-domain.com -k 4096 -w /var/www/discourse/public

Step 2 - discourse.conf

In addition to step 1 there is a change needed for nginx to correctly redirect http to https for anything other than DISCOURSE_HOSTNAME

    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /rewrite \^ https.+/
        to: |
          return 301 https://$host$request_uri;

We also need to remove the additional rewrite that web.ssl.template.yml adds since it forces only the DISCOURSE_HOSTNAME and now we have others!

    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /gzip on;[^\}]+\}/m
        to: |
          gzip on;

You may want to then add your own redirects.

It is working great for me issuing and updating 12 domains now, hopefully this is helpful to someone else!


Using Letsencrypt SSL in multi-site setup
Starting a second Discourse forum on the same VPS
Setting up Let's Encrypt
[Paid] Discourse configuration changes
Full site CDN acceleration for Discourse
Is it possible to verify both www and non-www version of my site using LetsEncrypt (using ./discourse-setup file)?
Is it possible to verify both www and non-www version of my site using LetsEncrypt (using ./discourse-setup file)?
Is it possible to verify both www and non-www version of my site using LetsEncrypt (using ./discourse-setup file)?
Setting up Let's Encrypt
(Brahn) #2

Note that as of a change to web.ssl.template.yml on Jun 6th there are a few adjustments needed to rebuild properly.

Fix the RegEx but also still change /$$ENV_DISCOURSE_HOSTNAME to $host:

    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /return 301 https.+/
        to: |
          return 301 https://$host$request_uri;

Edit to include the Strict-Transport-Security header as well but still overwrite the $http_host check applied by web.ssl.template.yml

    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /gzip on;[^\}]+\}/m
        to: |
          gzip on;
          add_header Strict-Transport-Security 'max-age=31536000'; # remember the certificate for a year and automatically connect to HTTPS for th$

(Fajfi) #3

It should be added in app.yml? What about Jun 6th update, this changes should be added instead of step 2?


(Brahn) #4

Yes, as mentioned in the topic lined at the top:

Correct, I cannot edit the original topic to change them. These two code blocks are instead of the two in the original.


(Fajfi) #5

Thanks for the answer. I’m testing this configuration but I’m getting redirection from domain2.com to domain1.com.

I want to have 2 discourse community on 1 docker with 2 domains: for example domain1.com and domain2.com.

Here’s my configuration: [YAML] # this is the all-in-one, standalone Discourse Docker container template ## ## - Pastebin.com, is there’s something bad according to this howto?


(Brahn) #6

I can’t see anything incorrect in the app.yml however, did you test the multisite on its own before adding the SSL? What I mean is, can you confirm that multisite is working already and the issue is when you add the SSL parts?


(Fajfi) #7

Yep, there’s problem with my multisite configuration. Maybe someone help me:


(Stephen) #8

Disable SSL and re-test, does the same issue present?

Are you using Cloudflare?


(Fajfi) #9

Unfortunately disabling ssl did not work and I dont know why :frowning: (more info in post above)


(Stephen) #10

Do you still have port 80 exposed?


(Fajfi) #11

Yes, 80 is exposed. Even if discourse should work only on 80 it keep redirecting me to https and I dont know why.


(Jay Pfaffman) #12

If your browser once found https it will want it forever. You might try another browser or perhaps clear your cache.


(Fajfi) #13

Ok, now for sure discourse in multisite without SSL works.

After rebuild and changes made to ssl (config above) secondsite get redirection to first site :frowning:
I clear all data in browser and problem still exist.

Here’s my tests discourse installation: d1.fajferek.pl - d2.fajferek.pl


(Brahn) #14

Inside the container, have a look at /etc/nginx/conf.d/discourse.conf and see what the rewrite shows. Maybe the replace is not working correctly anymore?

Also, what if this failed before and you now have cached certs?

See this comment about using FORCE=1


(Fajfi) #15

In the /etc/runit/1.d/letsencrypt I only found my 1st domain and also in discourse.conf there is no changes made in app.yml ;(

Is there any other solution to replace this by app.yml?


(Brahn) #16

Perhaps there is a problem with your app.yml then? I believe it can be sensitive to formatting. Double check for space/tabs in the wrong place, indenting, etc.

Maybe the blank line between the after_ssl and the - replace: matters?

after_ssl:

    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /-k 4096 -w \/var\/www\/discourse\/public/
        to: |
           -d www.domain1.com -d doman1.com -d www.domain2.com -d domain2.com -k 4096 -w /var/www/discourse/public

(from your earlier pastebin)

This is the most appropriate way I have found.