Skip to main content

Installing Discourse on Centos 8

Mongkok, Hongkong

Configure FirewallD

firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --zone=public --permanent --add-service=https
firewall-cmd --zone=public --permanent --add-service=pop3s
firewall-cmd --zone=public --permanent --add-service=smtp
firewall-cmd --reload
firewall-cmd --zone=public --list-services

Not sure if those are necessary (needs testing): firewall-cmd --permanent --zone=trusted --add-interface=docker0 firewall-cmd --permanent --zone=trusted --add-port=25/tcp

Download Discourse from Github

Create a /opt/discourse folder, where all the Discourse-related files will reside:

sudo mkdir /opt/discourse

Clone the official Discourse Docker Image into this /opt/discourse folder:

sudo git clone /opt/discourse

Configure Discourse

In this section we will configure your initial Discourse settings.

Switch to the /opt/discourse directory:

cd /opt/discourse

Copy the samples/standalone.yml file into the containers folder as app.yml:

sudo cp samples/standalone.yml containers/app.yml

Edit the Discourse configuration in the app.yml file:

sudo nano containers/app.yml

Set Mail Credentials

Enter your SMTP credentials in the lines for DISCOURSE_SMTP_ADDRESS, DISCOURSE_SMTP_PORT, DISCOURSE_SMTP_USER_NAME, and DISCOURSE_SMTP_PASSWORD. (Be sure you remove the comment # character from the beginnings of these lines as necessary.)

  LANG: en_US.UTF-8
  ## TODO: How many concurrent web requests are supported?
  ## With 2GB we recommend 3-4 workers, with 1GB only 2
  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example ','
  ## TODO: The mailserver this Discourse instance will use
  DISCOURSE_SMTP_ADDRESS:              # (mandatory)
  DISCOURSE_SMTP_PORT: 587                           # (optional)
  DISCOURSE_SMTP_USER_NAME:    # (optional)
  DISCOURSE_SMTP_PASSWORD: mypassword                # (optional)

The SMTP settings are required to send mail from your Discourse instance; for example, to send registration emails, password reset emails, reply notifications, etc.

Having trouble setting up mail credentials? See the Discourse Email Troubleshooting guide.

Setting up mail credentials is required, or else you will not be able to bootstrap your Discourse instance. The credentials must be correct, or else you will not be able to register users (including the admin user) for the forum.

Set Domain

Set DISCOURSE_HOSTNAME to This means you want your Discourse forum to be available at You can use an IP address here instead if you don’t have a domain pointing to your server yet. Only one domain (or IP) can be listed here.


Optional: Tune Memory Settings

Also in the env section of the configuration file, set db_shared_buffers to 128MB and UNICORN_WORKERS to 2 so you have more memory room.

db_shared_buffers: '128MB'

Save the app.yml file, and exit the text editor.

Bootstrap Discourse

Now use the bootstrap process to build Discourse and initialize it with all the settings you configured in the previous section. This also starts the Docker container.

sudo /opt/discourse/launcher bootstrap app

At this point I got an error message /usr/bin/env: ‘bash\r’: No such file or directory which suggests that the file launcher has Windows-style \r\n line endings instead of the \n-only line endings bash expects. To remove the \r chars run the following command:

sed $'s/\r$//' /opt/discourse/launcher > /opt/discourse/launcher-unix
chmod u+x /opt/discourse/launcher-unix

The chmod command makes the script executable. Then rerun the command above sudo /opt/discourse/launcher-unix bootstrap app.

At this point I ran into the problem that Docker was unable to download the discourse base image. And I had to download and save it on a different machine:

docker pull discourse/base:2.0.20191013-2320
docker save -o discourse.docker discourse/base:2.0.20191013-2320

The image file can then be transfered to the CentOS 8 machine and be loaded with the following command sudo docker load -i discourse.docker

This command will take about 8 minutes to run while it configures your Discourse environment. (Early in this process you will be asked to generate a SSH key; press Y to accept.)

After the bootstrap process completes, start Discourse:

sudo /opt/discourse/launcher start app

Access Discourse

Visit the domain or IP address (that you set for the Discourse hostname previously) in your web browser to view the default Discourse web page.

Discourse on CentOS 8

If you receive a 502 Bad Gateway error, try waiting a minute or two and then refreshing so Discourse can finish starting.

Sign Up and Create Admin Account

Use the Sign Up button at the top right of the page to register a new Discourse account. You should use the email address you provided in the DISCOURSE_DEVELOPER_EMAILS setting previously. Once you confirm your account, that account will automatically be granted admin privileges.

Once you sign up and log in, you should see the Staff topics and the Admin Quick Start Guide. It contains the next steps for further configuring and customizing your Discourse installation.

You can access the admin dashboard by visting /admin.

If you don’t get any email from signing up, and are unable to register a new admin account, please see the Discourse email troubleshooting checklist.

If you are still unable to register a new admin account via email, see the Create Admin Account from Console walkthrough, but please note that you will have a broken site until you get normal SMTP email working.


To upgrade Discourse to the latest version, visit /admin/upgrade and follow the instructions.

Install Plugins

In this tutorial, we’ll install Discourse Spoiler Alert and Discourse Sitemap plugin.

To install a plugin in Discourse, it needs to be placed in /var/www/discourse/plugins. However, this is inside the container - and changes to the container are wiped when it is rebuilt! So, the container definition is what needs to be edited.

  1. On your Centos system enter the Discourse directory: cd /opt/discourse.
  2. Edit the app configuration file: nano containers/app.yml.
  3. Access the Github page (discourse-sitemap, discourse-spoiler-alert) of each plugin you want to install, click on the green Clone or download button and copy the web URL.
  4. Now paste the URLs into the plugin section of the app.yml file:
## Plugins go here
## see for details
    - exec:
        cd: $home/plugins
          - git clone
          - git clone
          - git clone
  1. And rebuild the container: ./launcher rebuild app

What to do when you receive this error message:

[root@localhost discourse]# ./launcher rebuild app
Ensuring launcher is up to date
Fetching origin
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 2 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
   b637998..20e812e  master     -> origin/master
Updating Launcher
Updating b637998..20e812e
error: Your local changes to the following files would be overwritten by merge:
Please commit your changes or stash them before you merge.
failed to update

Stash your changes and rerun the rebuild command:

cd /opt/discourse
git stash
git pull
./launcher rebuild app

Once the rebuild process is done open Discourse again inside your browser and head to /admin/plugins to activate your new plugins:

Discourse on CentOS 8

All Plugins are update through /admin/upgrade:

Discourse on CentOS 8

The sitemap plugin publishes two files:

  1. /sitemap.xml : the regular Google Sitemap format
  2. /news.xml : special sitemap for Google News containing all new topics in the last three days

To test the spoiler plugin start a new thread and post:

[spoiler]This is a spoiler[/spoiler] 

Missing Certificate

Error message with /opt/discourse/launcher logs app:

[emerg] cannot load certificate '/shared/ssl/': PEM_read_bio_X509_AUX() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: TRUSTED CERTIFICATE)

Remove old certificate and rebuild:

rm -rf /opt/discourse/shared/standalone/ssl
rm -rf /opt/discourse/shared/standalone/letsencrypt
./launcher rebuild app

Forced Manual Renew

If this does not solve the issue try a manual renewal:

cd /opt/discourse
./launcher enter app
/shared/letsencrypt/  --issue -d --force --debug
/shared/letsencrypt/  --renew -d --force --debug

This will show you the issue - e.g. rate limit:

Create new order error. Le_OrderFinalize not found. {
  'type': 'urn:ietf:params:acme:error:rateLimited',
  'detail': 'Error creating new order :: too many certificates already issued for exact set of domains: see',
  'status': 429

Retry the renewal after a while or assign a different domain to your forum:

/opt/discourse/launcher enter app
service nginx stop
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
LE_WORKING_DIR=/shared/letsencrypt DEBUG=1 /shared/letsencrypt/ --issue -d -k 4096 -w /var/www/discourse/public
LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/ --installcert -d --fullchainpath /shared/ssl/ --keypath /shared/ssl/ --reloadcmd 'sv reload nginx'
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop