Http logo urls after enabling LetsEncrypt

I recently enabled letsencrypt for my instance by following this tutorial.

Now all the images uploaded via settings panel (logo, small logo, favicon) have http links in the design, resulting in mixed content error (although user avatars and uploads have correct https links). Reuploading them doesn’t change anything.

When I enable “force HTTPS” setting, the links end up looking like this (note how it’s forcing port 80):

I’m using v2.2.0.beta10 +21.

./launcher rebuild app didn’t help.

How do I fix this?

Was this server built using the standard install guide, or some other third-party package?

Is :80 specified in your app.yml at the end of the domain name? Check DISCOURSE_HOSTNAME - it shouldn’t include the port, but likely does based on what you’re reporting above. Remove the :80 from that line if so and rebuild. The only place :80 should appear in the YML file is the expose: section.

Force_HTTPS is required when Let’s Encrypt is enabled, the mixed content error is the result of an install without it enabled.


It was previously a bitnami install. The domain was the same, but SSL wasn’t enabled. I set up a new VPN, did the standard install, then migrated the data via the admin export/import feature. Then I enabled letsencrypt and rebuilt.

DISCOURSE_HOSTNAME is expose is the only place where 80 appears. Here’s my full config (some details censored):

## this is the all-in-one, standalone Discourse Docker container template
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
## visit to validate this file as needed

  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see for details
  - "80:80"   # http
  - "443:443" # https

  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  db_shared_buffers: "768MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

  LANG: en_US.UTF-8

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example ','

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate

  ## The CDN address for this Discourse instance (configured to pull)
  ## see for details

## The Docker container is stateless; all data is stored in /shared
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see for details
    - exec:
        cd: $home/plugins
          - git clone

## Any custom commands to run after building
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email=''"
  - exec: echo "End of custom commands"

Is your hostname actually

No, I censored it and some other details.

Would you be so kind and let us know the address for debugging?


This might seem like an odd question, but why wouldn’t you enable Let’s Encrypt prior to restoring your data?

Let’s Encrypt is part of the standard install, you almost have to go out of your way to not do it during setup. Enabling it prior to restoring a backup would let you verify that you have a known-good install with working SSL prior to re-introducing your data.

I don’t have much experience with discourse. I didn’t know I was supposed to enable SSL prior to importing data. I thought that importing might overwrite some settings.

The hostname and protocol are configured in the app.yml, which isn’t included in backups. Providing the backup file isn’t renamed it can be restored to another instance even if the FQDN doesn’t match.

I would work on getting Let’s Encrypt working with a standard install, then upload the backup, enable restore and restore your data.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

I tried a a fresh install on a new vps, but it broke again after importing data. After lots of googling and going through source code, I found out my Discourse.BaseUrl had port 80 forced into it. I tracked it down to these lines in discourse.rb:

 default_port = SiteSetting.force_https? ? 443 : 80
 url = +"#{base_protocol}://#{current_hostname}"
 url << ":#{SiteSetting.port}" if SiteSetting.port.to_i > 0 && SiteSetting.port.to_i != default_port

As a temporary fix, I commented out the last line, rebaked all the posts and that fixed everything for me.

Then I looked at my sql dump from the previous site export, and found out that port was set to 80 in site_settings (as I’ve mentioned, the original install didn’t have SSL). It didn’t match the port 443 which is expected from a site with force_ssl, and 80 was inserted into BaseUrl. So, I guess the proper fix is to change SiteSetting.port to 443 and then rebake.


This is a developer only setting, how did it get set? Discourse itself does not support running in production mode on any any ports other than the standard ones.

1 Like

I had a similar problem after moving to a two container configuration with nginx as the front end reverse proxy to a unix domain socket.

Everything works perfectly except that discourse was not changing http to https in the source and nginx does not rewrite / redirect this.

After a lot of digging around a days of trial and error, I finally found this command line setting:

cd /var/discourse
./launcher enter socket-only
rails c
SiteSetting.force_https = true

and verified:

postgres=# \c discourse
You are now connected to database "discourse" as user "postgres".
discourse=# select * from site_settings where name like '%http%';
 id |    name     | data_type | value |         created_at         |         updated_at         
 79 | force_https |         5 | t     | 2020-04-16 05:51:13.165124 | 2020-04-16 05:51:13.165124
(1 row)

discourse=# \q

Then, I restarted:

./launcher restart socket-only


It worked, finally after days of head scratching and trial and error, wondering why every tutorial, howto and readme on the wild, wild net did not work flawlessly.

Now, setting force_https = true , it worked flawlessly :slight_smile:

This must be like a hidden jewel in a video game and only gamers who find the hidden power can move on to the next level !! LOL. I’m there! A new discourse superpower!

1 Like