Putting in Discourse is very easy when its only one Discourse occasion on the server. Issues get difficult once you need to set up a number of Discourse situations on the identical server to cut back value.
The official Discourse set up doesn’t observe the common Docker practices. The Discourse installer first does one thing known as bootstrapping, which is able to seem to you as a bunch set up process. After the bootstrap course of is over, the launcher begins a container named “app” primarily based on the suggestions it took from you throughout the first time set up.
Such a hybrid set up process is totally different in the case of setting it up with different internet companies and functions like WordPress.
On this tutorial, I’ll present you the way to set up a number of Discourse set up together with different docker primarily based apps on a single Linux server. It’s not troublesome in any respect if you’re acquainted with fundamentals of Docker and Linux command line.
Putting in a number of Discourse boards on the identical server

Typically, a a number of discourse configuration is known as a multisite configuration and the method has been illustrated right here.
Formally, Discourse present no documentation for a number of Discourse set up on a single server. However fret not. I’ll present you set up course of for 3-5 standalone particular person containers operating beneath Nginx with every standalone container comparable to its personal respective area.
I’m utilizing Ubuntu 18.04 on this tutorial. Please just remember to have Docker put in on Ubuntu or whichever Linux distribution you might be utilizing.
I counsel utilizing a cloud server supplier like Linode for rapidly deploying a Linux server in cloud.
I’ve used area.com for instance area identify within the tutorial. Please be sure to change it in accordance with your individual domains or subdomains.
1. Change your area’s DNS information
In your area identify supplier’s DNS document panel, make it possible for each the area and subdomains (together with www) level to your server’s IP handle.
For instance, for root area, maintain the hostname subject clean (or @) and for subdomains, use a ‘*’ wildcard whereas setting the server IP.
2. Swap area
To ensure all of your container apps are comfy and by no means run out of reminiscence after you deploy them, it’s important that you’ve got the mandatory swap area in your system.
You possibly can at all times alter swap in accordance with the accessible RAM in your system. You possibly can determine the swap area primarily based on the bundle of app containers on the only server and estimating their cumulative RAM utilization. Discourse additionally checks and configures swap for you.
3. Create a Docker community
This docker community will allow containers to speak with one another as required. Let’s name it chain for simpler understanding.
You’ll use this community when configuring all of your containers.
docker community create chain
4. Setup Nginx Reverse Proxy
Now proceed with organising Nginx Reverse Proxy. Word that this acts as an interface that may map all totally different container ports on itself so as to entry them by URLs. You can too seek advice from it because the ‘mom container’.
docker run –name nginx-proxy –net chain -p 80:80 -p 443:443 -v ~/certs:/and so on/nginx/certs -v /and so on/nginx/vhost.d -v /usr/share/nginx/html -v /var/run/docker.sock:/tmp/docker.sock:ro –label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy -d –restart at all times jwilder/nginx-proxy
5. Setup Let’s Encrypt Nginx Proxy Companion
Word that we inform docker to make use of volumes that’s already declared on the primary nginx-proxy container. It’s utilizing the identical “chain” community you created in step 3.
docker run –name letsencrypt-nginx-proxy-companion –net chain -v ~/certs:/and so on/nginx/certs:rw -v /var/run/docker.sock:/var/run/docker.sock:ro –volumes-from nginx-proxy -d –restart at all times jrcs/letsencrypt-nginx-proxy-companion
This companion container for nginx-proxy takes care of organising SSL certificates with Let’s Encrypt. You will note that whereas lastly organising your Discourse containers.
6. WWW Redirection by Nginx (CNAME not required, non-compulsory step for utilizing subdomains)
To make sure redirection of area.com requests to www.area.com like every other web site, you must carry out one extra step.
Enter the nginx-proxy container:
docker exec -ti nginx-proxy /bin/bash
You’ll now see a root immediate like this:
[email protected]:/app#
Bear in mind the /and so on/nginx/vhost.d location I discussed in step 4? Create a brand new file right here that’ll be the identical as your root area identify. You don’t have vim or nano right here. As a substitute of putting in Vim or Nano, use the cat command.
cat >> /and so on/nginx/vhost.d/area.com
On the subsequent immediate, no matter you write shall be enhancing the file. So just remember to exchange www.area.com with your individual area within the subsequent line:
rewrite ^/(.*)$ https://www.area.com/$1 everlasting;
Press enter after which Ctrl+D to reserve it. Enter exit to get out of the container.
[email protected]:/app# exit
Let’s cease all of the above containers (within the given order) you’ve created till now. You received’t use restart, simply begin them once more as you don’t need different containers listening when restarting every of them.
docker cease nginx-proxy
docker cease letsencrypt-nginx-proxy-companion
docker begin nginx-proxy
docker begin letsencrypt-nginx-proxy-companion
7. Clone the official Discourse Docker picture
As per the official information, clone the official discourse docker picture into /var/discourse listing. That is the place Discourse can retailer all its Docker volumes belonging to its respective containers after setup.
sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
8. Copy the Standalone configuration
Now the subsequent step is to make sure you copy the file /var/discourse/standalone.yml to /var/discourse/containers/ as app.yml earlier than enhancing it in accordance with your necessities.
cp /var/discourse/samples/standalone.yml /var/discourse/containers/app.yml
A typical standalone.yml appears to be like like this.
9. Put together the Standalone configuration
You now must edit this file as a result of your configuration goes to primarily based on nginx.
The ports 80 and 443 are already in use by the identical. You even have our letsencrypt container already and it’s a must to present Discourse your present Docker community you need to put it in.
Whereas setting your area right here, you’ll additionally want a mail server to configure your discussion board notification emails (I’ve used Sendgrid right here).
Word that LETSENCRYPT_EMAIL (for notifying SSL updates)and DISCOURSE_DEVELOPER_EMAILS (for admin) could be totally different if required.
nano /var/discourse/containers/app.yml
10. Customise the Standalone Configuration
Following is my edited file renamed as app.yml for demonstration function. It is suggested to edit your individual yml file to keep away from alignment points.
that is the all-in-one, standalone Discourse Docker container template
#
After making adjustments to this file, you MUST rebuild
/var/discourse/launcher rebuild app
#
BE VERY CAREFUL WHEN EDITING!
YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
go to http://www.yamllint.com/ to validate this file as wanted
templates:
“templates/postgres.template.yml”
“templates/redis.template.yml”
“templates/internet.template.yml”
“templates/internet.ratelimited.template.yml”
Uncomment these two traces for those who want to add Lets Encrypt (https)
#- “templates/internet.ssl.template.yml”
#- “templates/internet.letsencrypt.ssl.template.yml”
which TCP/IP ports ought to this container expose?
In order for you Discourse to share a port with one other webserver like Apache or nginx,
see https://meta.discourse.org/t/17247 for particulars
expose:
– “80”
#- “80:80” # http
#- “443:443” # https
docker_args:
– “–net chain”
params:
db_default_text_search_config: “pg_catalog.english”
## Set db_shared_buffers to a max of 25% of the entire reminiscence.
## shall be set routinely by bootstrap primarily based on detected RAM, or you’ll be able to override
#db_shared_buffers: “256MB”
## can enhance sorting efficiency, however provides reminiscence utilization per-connection
#db_work_mem: “40MB”
## Which Git revision ought to this container use? (default: tests-passed)
#model: tests-passed
env:
LANG: en_US.UTF-8
# DISCOURSE_DEFAULT_LOCALE: en
## What number of concurrent internet requests are supported? Is dependent upon reminiscence and CPU cores.
## shall be set routinely by bootstrap primarily based on detected CPUs, or you’ll be able to override
#db_shared_buffers: “256MB”
## can enhance sorting efficiency, however provides reminiscence utilization per-connection
#db_work_mem: “40MB”
## Which Git revision ought to this container use? (default: tests-passed)
#model: tests-passed
env:
LANG: en_US.UTF-8
# DISCOURSE_DEFAULT_LOCALE: en
## What number of concurrent internet requests are supported? Is dependent upon reminiscence and CPU cores.
## shall be set routinely by bootstrap primarily based on detected CPUs, or you’ll be able to override
#UNICORN_WORKERS: 3
## TODO: The area identify this Discourse occasion will reply to
## Required. Discourse is not going to work with a naked IP quantity.
DISCOURSE_HOSTNAME: ‘area.com’
VIRTUAL_HOST: ‘area.com,www.area.com’
LETSENCRYPT_HOST: ‘area.com,www.area.com’
LETSENCRYPT_EMAIL: ‘electronic [email protected]’
## Uncomment if you would like the container to be began with the identical
## hostname (-h choice) as specified above (default “$hostname-$config”)
#DOCKER_USE_HOSTNAME: true
## TODO: Record of comma delimited emails that shall be made admin and developer
## on preliminary signup instance ‘[email protected],[email protected]’
DISCOURSE_DEVELOPER_EMAILS: ‘electronic [email protected]’
## TODO: The SMTP mail server used to validate new accounts and ship notifications
# SMTP ADDRESS, username, and password are required
# WARNING the char ‘#’ in SMTP password may cause issues!
DISCOURSE_SMTP_ADDRESS: smtp.sendgrid.internet
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: apikey
DISCOURSE_SMTP_PASSWORD: yourpassword
DISCOURSE_SMTP_ENABLE_START_TLS: true # (non-compulsory, default true)
## In case you added the Lets Encrypt template, uncomment under to get a free SSL certificates
#LETSENCRYPT_ACCOUNT_EMAIL: [email protected]
## The http or https CDN handle for this Discourse occasion (configured to tug)
## see https://meta.discourse.org/t/14857 for particulars
#DISCOURSE_CDN_URL: https://discourse-cdn.instance.com
The Docker container is stateless; all information is saved in /shared
volumes:
quantity:
host: /var/discourse/shared/standalone
visitor: /shared
quantity:
host: /var/discourse/shared/standalone/log/var-log
visitor: /var/log
Plugins go right here
see https://meta.discourse.org/t/19157 for particulars
hooks:
after_code:
– exec:
cd: $house/plugins
cmd:
– git clone https://github.com/discourse/docker_manager.git
Any customized instructions to run after constructing
run:
exec: echo “Starting of customized instructions”
## If you wish to set the ‘From’ electronic mail handle to your first registration, uncomment and alter:
## After getting the primary signup electronic mail, re-comment the road. It solely must run as soon as.
#- exec: rails r “SiteSetting.notification_email=’[email protected]’”
exec: echo “Finish of customized instructions”
Double checks the next particulars:
Port configuration needs to be:
expose:
– “80”
# – “80:80” # http
# – “443:443” # https
Current community identify correctly configured within the file as proven above.
docker_args:
– “–net chain”
In any other case, you’ll see a clean web page once you verify your area after set up.
12. Bootstrap and Launch
After saving the above file, run the next instructions:
cd /var/discourse
./launcher bootstrap app
This can take a substantial period of time. In the long run of the bootstrap course of, you’ll be requested to:
./launcher begin app
Word that for those who had named the file as xyz.yml, the command would have been modified accordingly (./launcher begin xyz).
It’s the identify of the container operating that you may verify with “docker ps“. Now once you go to the area in your browser, you will note the next web page:
Discourse Put in
13. SSL Settings
From this level on, the registration course of is sort of simple. After you have accomplished the registration, within the Docker admin dashbaird, go to settings>safety and allow “pressure https”.

After saving it, cease the container and begin it once more:
./launcher cease app
./launcher begin app
After a couple of moments SSL will begin working in your discussion board. Ensure you additionally deal with the dependencies for https.
14. Set up extra Discourse situations in additional standalone containers
For extra Discourse containers, it’s a must to repeat the identical course of once more from Step 8.
Initially, you used app. Now you must use different names like app2, app3 and so on.
cp /var/discourse/samples/standalone.yml /var/discourse/containers/app2.yml
An additional step would even be required for every of them to specify a brand new location (say standalone2, standalone3 and so forth) of their respective yml recordsdata for the Docker volumes (verify step 10). After all, you’ll have to alter the area identify as properly.
## The Docker container is stateless; all information is saved in /shared
volumes:
quantity:
host: /var/discourse/shared/standalone2
visitor: /shared
quantity:
host: /var/discourse/shared/standalone2/log/var-log
visitor: /var/log
With this, observe the remainder of the steps and also you’ll have extra Discourse put in on the identical server.
Hope you discover this text helpful in organising a couple of Discourse boards with their respective Docker containers.
In case you have questions or options, please be happy to depart a remark under.