Discourse + NGINX

I've taken an interest in Discourse and followed steps to get it up and running, I'm up to the part where you build it and after that I started looking at the config containers/app.yml which displays the settings for discourse to work how you want it. However, I am confused on how to run nginx on the same machine as discourse.

I'm not sure what nginx.conf I should edit (external nginx or discourse nginx) since it didn't work, it just went to my external site as normal plus I could not find nginx inside the container, either that or I'm blind.

I'll provide any logs and configs you wish, but passwords and sensitive information will be censored.

NOTE: I'm still also building my external site (external site meaning nginx outside of discourse), so please forgive the mess.

ADDED: I wonder if these are viable:-

So, I've answered my own question based on a mistake, here's how I did it:

NOTE: Make sure you have a sub-domain otherwise this won't work.

Went into /var/discourse/containers/app.yml and did this:-

# base templates used; can cut down to include less functionality per container templates:
  - "templates/cron.template.yml"
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/sshd.template.yml"
  - "templates/web.template.yml"
  # - "templates/web.ssl.template.yml" # remove - https will be handled by outer nginx
  - "templates/web.ratelimited.template.yml"
  - "templates/web.socketed.template.yml"  # <-- Added
# which ports to expose?
expose:
 # - "80:80" # fwd host port 80 to container port 80 (http)
 # - "443:443" # fwd host port 443 to container port 443 (https)
  - "2222:22" # If you don't need to use ./launcher ssh app, you can remove this too

Now MAKE SURE YOU DISABLE YOUR PORT 80 AND 443! THIS IS VERY IMPORTANT.

Next is to configure a NEW configuration file called discourse.conf in your /etc/nginx/conf.d/ then make the following changes:-

For HTTP

server {
	listen 80; listen [::]:80;
	server_name forum.example.com;  # <-- change this

	location / {
		proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
		proxy_set_header Host $http_host;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

For HTTPS

server {
    listen 80; listen [::]:80;
    server_name forum.example.com;  # <-- change this

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl spdy;  listen [::]:443 ssl spdy;
    server_name forum.example.com;  # <-- change this

    ssl on;
    ssl_certificate      /var/discourse/shared/standalone/ssl/ssl.crt;
    ssl_certificate_key  /var/discourse/shared/standalone/ssl/ssl.key;
    ssl_dhparam          /var/discourse/shared/standalone/ssl/dhparams.pem;
    ssl_session_tickets off;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

    # enable SPDY header compression
    spdy_headers_comp 6;
    spdy_keepalive_timeout 300; # up from 180 secs default

    location / {
        proxy_pass https://unix:/var/discourse/shared/standalone/nginx.https.sock:;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

But wait, there's more to do before you rebuild the discourse container and reload nginx, on to the next step!

^Source: https://meta.discourse.org/t/running-other-websites-on-the-same-machine-as-discourse/17247

Here you will add a little mistake I made, I've tried many methods, when I try new methods I go through a routine delete phase so settings from previous methods don't collide...in this case I forgot to delete this one.

In my setup I use the default.conf, not the enabled-site config to make changes, my enabled-site config has the default.conf templated. So for this example, I will use default.conf.

Edit your /etc/nginx/conf.d/default.conf and add the following:-

upstream discourse {
    server 127.0.0.1:80 fail_timeout=0;
}

Then in your server { listen 443; } block add this:-

  location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://discourse;
  }

^Source: https://www.digitalocean.com/community/questions/need-help-with-installing-discourse-and-wordpress

Now we do four things:

  1. Make sure discourse is not running /var/discourse/launcher stop app || true
  2. Check if nginx is ok with the setup with a sudo nginx -t
  3. If all is well do a reload sudo service nginx reload
  4. Lastly rebuild the container /var/discourse/launcher rebuild app

ANNNNNNNND, that's it, this is how I got it working, if there is a simpler and more efficient way of doing this please share. I would really like to know where I messed up.

2 Likes

Thanks for posting this. I found your post here https://forum.teksyndicate.com/t/discourse-and-letsencrypt-with-external-nginx/100209/13 and I was having the same problem. Very grateful you've posted what you've worked out - thanks!

I'd just like to clarfiy though, when you talk about editing /etc/nginx/conf.d/default.conf, this is a new file that you are creating? Not just editing the /etc/nginx/conf.d/discourse.conf? I wasn't sure if it was a typo.

If this is a new file, given discourse.conf has a server { listen 443; } block already, what are you putting in this block in default.conf?

Also, can you please clarify what you mean by:

Thanks a lot.

This file should already be in the /etc/nginx/conf.d directory since it's installed by default with nginx. Before I change any file I make a backup of it, for e.g. cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak

Discourse is set to use the discourse.conf file from it's templates

This is a line of code that you can see in your /etc/nginx/nginx.conf , it's an include /etc/nginx/conf.d/*.conf. I've made modifications that didn't need to make my ~/sites-enabled/example.com templated into my ~/conf.d/default.conf when I got my linode server. I've also fixed the HTTPS issue, however I still haven't got a reply from the discourse community about the SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET bug. The reason I say bug is because you cannot access the forums directly unless you went to the homepage/website first.