This guide is only for existing installs where HTTPS is not enabled. Following the official setup guide automatically enables HTTPS by default.
So you’d like to add https to your Discourse absolutely free, courtesy of our friends at Let’s Encrypt?
Is everything else on your site ready for HTTPS?
./discourse-setup will enable Let’s Encrypt. And as of March 2017, you can run it again, and press return a few times and enter your email address ; the script will include the required templates and insert your email address as required. Unless you are an expert sysadmin and know a reason not to do that, you should run
discourse-setup rather than read any further. (If you installed Discourse a long time ago, you might still have to edit
app.yml by hand.)
Note: If your Discourse is accessed via some reverse proxy (e.g., Cloudflare) this will not work.
For the next few steps, you will be editing the
app.yml file for your Discourse instance:
cd /var/discourse nano containers/app.yml
Is Discourse the only website on your server?
If you are already using
web.socketed.template.yml, because you host other websites via port 80 on the same server, stop. You should be using a Let’s Encrypt client on the host system; the validation will fail as the client used is unable to bind to the necessary sockets.
templates: - "templates/web.template.yml" - "templates/web.ssl.template.yml" - "templates/web.letsencrypt.ssl.template.yml"
2. Expose port 443
expose: - "80:80" - "443:443"
3. Add email account to register with Let’s Encrypt
env: LETSENCRYPT_ACCOUNT_EMAIL: 'email@example.com'
4. Rebuild your container
./launcher rebuild <container name>
After that completes, load the site in your browser using
https:// – it should “just work!”
5. Adjust your dependencies for HTTPS
Check all your social logins and make sure they are pointing to the
http://versions of your site’s authentication URLs.
If you are using a CDN, you will need to switch your CDN to use
http://to pull resources.
If your browser does not show any warnings in its f12 console in the security about insecure assets:
force_httpswill be enabled automatically when you rebuild and a valid certificate is installed.
How does it work?
The template uses GitHub - acmesh-official/acme.sh: A pure Unix shell script implementing ACME client protocol which is
Simplest shell script for LetsEncrypt free Certificate client
Simple and Powerful, you only need 3 minutes to learn.
Pure written in bash, no dependencies to python , acme-tiny or LetsEncrypt official client. Just one script, to issue, renew your certificates automatically.
Probably it’s the smallest&easiest&smartest shell script to automatically issue&renew the free certificates from LetsEncrypt.
web.letsencrypt.ssl.template.yml adds a startup script to your container that
- Issues a Let’s Encrypt cert using the standalone mode. It boots a standalone server that listens on port
80but this happens before
nginxis up so port 80 is free.
- Installs the cert into the right directory that
nginxexpects. At the same time, it adds a cron job that runs a daily cert renewal check. This will automatically renew your cert. Nothing happens if cert has not expired. If the certificate does expire, you’ll get an email about it from Let’s Encrypt at the email address you provided during setup.
- Switches the script to use the webroot plugin with
/var/www/discourse/publicas the directory. This will allow us to use
nginxas the server that handles domain validation. Zero downtime during cert renewal!
Check logs for cert related errors
./launcher logs <container name>
Then look for any errors mentioning
Did the cert files get written OK?
ls -l /var/discourse/shared/standalone/ssl on the host server
You should have a certificate
.cer and key
.key file for your domain, and they should have ~3k filesize.
-rw-r--r-- 1 root root 424 May 18 03:22 dhparams.pem -rw-r--r-- 1 root root 3823 May 18 04:24 discourse.example.com.cer -rw-r--r-- 1 root root 3243 May 18 04:24 discourse.example.com.key
Manually reissue the cert
./launcher enter app sv stop nginx /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf LE_WORKING_DIR=/shared/letsencrypt DEBUG=1 /shared/letsencrypt/acme.sh --issue -d example.com -k 4096 -w /var/www/discourse/public LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --installcert -d example.com --fullchainpath /shared/ssl/example.com.cer --keypath /shared/ssl/example.com.key --reloadcmd "sv reload nginx" /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
Delete the old cert files and try rebuilding again
rm -rf /var/discourse/shared/standalone/ssl rm -rf /var/discourse/shared/standalone/letsencrypt ./launcher rebuild app
Though the Let’s Encrypt certificate is valid and safe for encrypting data, it does not certify that the site is owned by a particular organization. Firefox will complain that the certificate “does not supply ownership information.” This is a limitation of how Let’s Encrypt works. For more information see: Adding Ownership Information? - #8 by tialaramex - Help - Let's Encrypt Community Support.