How to set up Discourse on a server with existing Apache sites

It’s not as daunting as it sounds!

As you probably know, the only supported installs of Discourse are the Docker installs. While this may sound a bit intimidating at first, it’s really not all that bad. You basically need to do two things:

  1. Install HAProxy (or an alternative) which will take over port 80 and then divert your Discourse traffic to your docker container, and all your other sites to your usual Apache set-up.

  2. Let Apache know which port to listen for.

While this is only a rough guide, it should do a good job of pointing you in the right direction. Let’s get started!

Upgrade your kernel

I personally recommend you upgrade your kernel as docker works better with the latest kernels. Just Google how to upgrade your kernel for your distro.

Edit: This may not be such a good idea after all as Docker will only support certain kernels with certain distros. So if you can, upgrade your OS instead.

Install Docker

I used the CentOS guide here: (you only need to go as far as installing docker - you don’t need to pull any images)

Then start it, and set it to start on boot.

Edit: Discourse works best with the latest Docker version, for CentOS upgrade as per instructions here:

Install Discourse

Follow the install instructions (start from here: discourse/ at master · discourse/discourse · GitHub). When you come to edit app.yml, under “## which TCP/IP ports should this container expose?” you want:

"8888:80" # fwd host port 8888 to container port 80 (http)

Once it’s all installed you can continue setting up your Discourse forum after the rest of the steps below.

Install HAProxy

On CentOS it’s yum install haproxy.

Then edit your config, to something like this:

    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #    local2.*                       /var/log/haproxy.log
    log local2
    # chroot      /var/lib/haproxy
    pidfile     /var/run/
    maxconn     4000
    user        haproxy
    group       haproxy
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
frontend http-in
        bind *:80
        default_backend main_apache_sites
        # Define hosts
        acl host_discourse hdr(host) -i
        # figure out which one to use
        use_backend discourse_docker if host_discourse
backend main_apache_sites
    server server1 cookie A check
backend discourse_docker
    server server2 cookie A check

Edit Apache config

Edit the Apache config to listen on port 8080: Listen *:8080
Edit all of the existing virtual host files for each domain to reflect this change (first line should read) <VirtualHost *:8080>

Install mod_extract_forwarded

You’ll want to install this or everyone’s IP will be of your servers. For CentOS see the guide here

For Centos 7, use: mod_remoteip - Apache HTTP Server Version 2.5

Configure NGINX (Discourse)

Add the following as a plugin (to the bottom of your app.yml):

  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        types {

Start HAProxy, restart apache and proceed to set up your discourse install

Set HAProxy to start to start on boot, start it, and then restart Apache to pick up your changes and you should be all sorted. All you’ve got left to do is set up your Discourse install.

Can a mod please edit this in to the end of the first post please…

Enabling HTTPS

Here are some notes on enabling HTTPS:

  • It’s easier than you think!
  • You don’t need to worry whether your sites are served via Docker, or Apache - it’s HAProxy that speaks to the browser so you can let HAProxy handle it all.
  • You simply need to add bind *:443 ssl crt /etc/haproxy/certs/ to your front-end then just make sure your certs are in that directory.
  • See this article on how to set-up and renew Lets Encrypt certs.

That’s it!

Thanks to @macsmith71 for his help with HAProxy :slight_smile:
If I’ve missed anything out please let me know, it’s way past my bed time :stuck_out_tongue:


As an alternative you can install the Nginx proxy before Apache.
Here is my real locahost config for a Discourse forum in the root and a Magento 2.0 store in the /store subfolder: How to install Magento 2.0 into subdirectory using Nginx + Apache - Magento 2


This also works on a CPanel server for me. I followed all instructions and I set

backend main_apache_sites
server server1 *:8080 cookie A check
backend discourse_docker
server server2 *:8888 cookie A check

instead of

backend main_apache_sites
server server1 cookie A check
backend discourse_docker
server server2 cookie A check

1 Like

What if I wanted to use https for this. Is it possible? and what additional step do I have to do in order to do so
(I have already got the regular http working, but I want https included since I’m using LetsEncrypt for https (SSL)

EDIT: I have fixed it


Can you share what you did please? I am due to set this up to and will be interested in learning how you went about it @Daffy_Chu

1 Like

Currently I have only gotten it work for normal sites thats not discourse, as I’m having subdomain issue just for discourse. But the way I enabled the SSL in HAProxy was just by simplify adding
bind *:443 ssl crt /etc/haproxy/certs/cert.pem
into your HAProxy config under your
bind *:80
As well as since I also changed my apache SSL Port to 4444, I had to add listening to SSL line
backend main_apache_sites server server1 *:8080 cookie A check server server1 *:4444 check ssl verify none #added backend discourse_docker server server2 *:8888 cookie A check


I am new to Linux. Thing are different in my Ubuntu set up, like the syslog stuff in haproxy text. I was wonder you could update the guide and possibly break it down Barney style.

So I set this up on a local server at my university, and it works 99%. One problem is that the forums are now served at $hostname:8888/ instead of just $hostname, and uploads are broken. See below topic for more details.
@AstonJ, how did you get around this issue?

Did you edit app.yml?

But I cannot successfully run ./discourse-setup for the very reason I come here: port 80 is occupied. Not running discousse-setup means I don’t have app.yml file.

One way is to temporarily stop apache2, install discourse and then editing the app.yml then enabling apache2 back.


I cannot do that. There are important services on port 80 and 443. I started that docker-based install in the hope it won’t interfere with anything else.

So the graph now:

  1. Trying to install discourse in docker

  2. As Getting started suggests, started the linked readme.

  3. At whatever I’ve been bitten by:

     root@mercury MERCURY# ./discourse-setup 
     Port 80 appears to already be in use.
     This will show you what command is using port 80
     docker-pr 26716 root    4u  IPv6 2243472      0t0  TCP *:http (LISTEN)
     If you are trying to run Discourse simultaneously with another web
     server like Apache or nginx, you will need to bind to a different port
     If you are reconfiguring an already-configured Discourse, use 
     ./launcher stop app
     to stop Discourse before you reconfigure it and try again.
  4. Ok let’s see what the mentioned link offers:

    If you have not already, please read the Advanced Troubleshooting with Docker guide, as it covers the basics on the separation between host and container.

    Ok, going to that post…

    But where am I exactly? Just trying to setup discourse for port other than 80, and still have no clue how to do that. I still don’t have an app.yml yet. :disappointed:

in the samples directory there is a file called standalone.yml and ./discourse-setup makes the app.yml using that file and tweaking a few values depending upon your system.

if you can do it by hand then feel free to try out.


Tried out, has the following issue: Install Discourse, change docker port 80

Sorry, not sure where to post.