# Set up HTTPS support with Let's Encrypt

**URL:** https://meta.discourse.org/t/set-up-https-support-with-lets-encrypt/40709
**Category:** Self-Hosting
**Tags:** how-to, domains
**Created:** [March 8, 2016, 12:10am UTC](https://meta.discourse.org/t/set-up-https-support-with-lets-encrypt/40709 "2016-03-08T00:10:00Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [March 8, 2016, 12:10am UTC](https://meta.discourse.org/t/set-up-https-support-with-lets-encrypt/40709/1 "2016-03-08T00:10:00Z")

</div>

> 🔖 This is a guide for enabling HTTPS on an existing Discourse installation using Let’s Encrypt. It assumes prior installation without HTTPS enabled.
> 
> 🙋 Required user level: System Administrator
> 
> ❗ This guide is only for existing installs where HTTPS is not enabled. Following the [official setup guide](https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md) 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?](https://letsencrypt.org/)

> #### 🔔 Is everything _else_ on your site ready for HTTPS?

Before you start, please bear in mind that for HTTPS to work properly, _every single resource_ on the page must be HTTPS compatible. Consider your CDN, your social logins, your logo files, any third party JavaScript, images, fonts, or css — these _all_ must be available over HTTPS!

**Note:** `./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 configuration will not work.

## Configure HTTPS with Let’s Encrypt

### 1. Edit `app.yml`

Access your Discourse’s configuration file:

```bash
cd /var/discourse
nano containers/app.yml

```

- Add the following templates:

```yaml
templates:
  - "templates/web.template.yml"
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.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.

### 2. Expose HTTPS ports

Ensure the following ports are exposed for HTTPS traffic:

```yaml
expose:
  - "80:80"
  - "443:443"

```

### 3. Add email for Let’s Encrypt

Insert the email address for Let’s Encrypt notifications:

```yaml
env:
  LETSENCRYPT_ACCOUNT_EMAIL: 'your-email@example.com'

```

### 4. Rebuild the application

Apply the changes by rebuilding the container:

```bash
./launcher rebuild app

```

### 5. Validate HTTPS

Access your site via `https://yourdomain.com`. If successful, you’ll see your site secured with HTTPS.

Review your resources:

- Ensure assets (e.g., images, scripts) load over HTTPS.
- Reconfigure social logins and CDN for HTTPS as required.
- Address any warnings in the browser console about insecure assets.

Discourse automatically enables `force_https` after a rebuild with a valid HTTPS certificate.

## How does it work?

The template uses [GitHub - acmesh-official/acme.sh: A pure Unix shell script ACME client for SSL / TLS certificate automation · GitHub](https://github.com/acmesh-official/acme.sh) 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 boot script to your container that

1. Starts a lightweight nginx to serve ACME challenges on port `80` before the main `nginx` is up.
2. Issues both an RSA (4096-bit) and an ECDSA (ec-256) Let’s Encrypt certificate using webroot mode with `/var/www/discourse/public` as the directory.
3. Installs the certificates into the `/shared/ssl/` directory that `nginx` expects. At the same time, **it sets up a cron job for automatic certificate renewal**. This will automatically renew your certs. Nothing happens if certs have not expired. If a certificate does expire, you’ll get an email about it from Let’s Encrypt at the email address you provided during setup.
4. Sets `force_https` to true if valid certificates are obtained.

## Troubleshooting

### Checking logs

If HTTPS doesn’t work, check logs for SSL or Let’s Encrypt errors with:

```plaintext
./launcher logs app

```

### Verifying certification files

Ensure certificate and key files are in place with:

```plaintext
ls -l /var/discourse/shared/standalone/ssl

```

You should see files like:

- `yourdomain.com.cer` (RSA)
- `yourdomain.com.key` (RSA)
- `yourdomain.com_ecc.cer` (ECDSA)
- `yourdomain.com_ecc.key` (ECDSA)

### Renewing certificates manually

If auto-renewal fails, you can manually reissue your certificates:

```plaintext
./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"
LE_WORKING_DIR=/shared/letsencrypt DEBUG=1 /shared/letsencrypt/acme.sh --issue -d example.com --keylength ec-256 -w /var/www/discourse/public
LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --installcert --ecc -d example.com --fullchainpath /shared/ssl/example.com_ecc.cer --keypath /shared/ssl/example.com_ecc.key --reloadcmd "sv reload nginx"
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop

```

### Rebuilding with clean certs

Remove old certificate files and rebuild to start afresh:

```plaintext
rm -rf /var/discourse/shared/standalone/ssl
rm -rf /var/discourse/shared/standalone/letsencrypt
./launcher rebuild app

```

## Limitations

Let’s Encrypt certificates only validate the domain and encryption. They don’t confirm ownership or identity, which may be flagged in some browsers. For more details, refer to the [Let’s Encrypt community](https://community.letsencrypt.org/).

> Last edited by @SaraDev 2024-12-06T21:47:31Z
> 
> > **Check document**
> >
> > Perform check on document:

---

_[View the full topic](https://meta.discourse.org/t/set-up-https-support-with-lets-encrypt/40709)._
