Discourse is an open source community discussion platform built for the modern web.
This tutorial will walk you through the steps of configuring Discourse, moving it behind a reverse proxy with Nginx, and configuring an SSL certificate for it with Let’s Encrypt. Moving Discourse behind a reserve proxy provides you with the flexibility to run other websites on your Droplet.
Before we get started, be sure you have the following:
All the commands in this tutorial should be run as a non-root user. If root access is required for the command, it will be preceded by sudo
.
Now that you have Discourse installed, we need to configure it to work behind Nginx.
Warning: This will incur downtime on your Discourse forum until we configure Nginx. Make sure this is a fresh install of Discourse or have a backup server until configuration is complete.
There’s just one setting we’ll need to change to Discourse so we can move it behind Nginx. Change into the directory that contains the configuration file:
- cd /var/discourse
Then, open the configuration file we need to change:
- sudo nano containers/app.yml
Using the arrow keys, scroll down to the expose
section (it should be near the top) and change the first port number on this line:
...
## which TCP/IP ports should this container expose?
expose:
- "25654:80" # fwd host port 80 to container port 80 (http)
...
This number can be random and shouldn’t be shared with others. You can even block unauthorized access to it with an iptables firewall rule if you’d like.
Now save and exit the text editor.
Enable the configuration change by running:
- sudo ./launcher rebuild app
This step might take a while, so please be patient.
You can verify everything is working by visiting your website. Your domain name for Discourse (such as http://discourse.example.com
) will no longer load the interface in a web browser, but it should be accessible if you use the port just configured for Discourse such as http:///discourse.example.com:25654
(replace discourse.example.com with your domain name and 25654 with the port you just used in this step).
Now that Discourse is installed and configured to work behind Nginx, it is time to install Nginx.
To install Nginx on Ubuntu, simply enter this command and the installation will start:
- sudo apt-get install nginx
Browsing to your old Discourse URL at http://discourse.example.com
will show the default Nginx webpage:
This is fine. We’ll change this to your forum now. First, let’s stop Nginx:
- sudo service nginx stop
Then, delete this default webpage configuration — we won’t need it:
- sudo rm /etc/nginx/sites-enabled/default
Next, we’ll make a new configuration file for our Discourse server, which we’ll name discourse
.
- sudo nano /etc/nginx/sites-enabled/discourse
Copy and paste in the following configuration. Replace discourse.example.com
with your domain name and 25654
with the port you just used in the previous step:
server {
listen 80;
server_name discourse.example.com;
return 301 https://discourse.example.com$request_uri;
}
server {
listen 443 ssl spdy;
server_name discourse.example.com;
ssl_certificate /etc/letsencrypt/live/discourse.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/discourse.example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
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';
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://discourse.example.com:25654/;
proxy_read_timeout 90;
proxy_redirect http://discourse.example.com:25654/ https://discourse.example.com;
}
}
Here’s what this config does:
discourse.example.com
domain on port 80, and it redirects all requests to SSL on port 443. This is optional, but it forces SSL on your website for all users.25654
(in this case, Discourse). This essentially uses a reverse proxy to send Discourse pages to your users and back over SSL.You may have noticed we’re referencing some certificates at /etc/letsencrypt
. In the next step we’ll generate those before restarting Nginx.
To generate the SSL certificates, we will first install the Let’s Encrypt’s ACME client. This software allows us to generate SSL certificates.
- sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
Then go to the letsencrypt
directory:
- cd /opt/letsencrypt/
Install the packages required by Let’s Encrypt the first time:
- ./letsencrypt-auto --help
Now we can generate your certificates by running (replace with your email address and domain name):
- ./letsencrypt-auto certonly --standalone --email sammy@example.com --agree-tos -d discourse.example.com
Note: Let’s Encrypt will only issue certificates for domain names. You will get an error if you try to use an IP address. If you need a domain name, check out the links in the Prerequisites section.
You should get a response fairly quickly, similar to this:
IMPORTANT NOTES:
- If you lose your account credentials, you can recover through
e-mails sent to sammy@example.com.
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/discourse.example.com/fullchain.pem. Your
cert will expire on 2016-04-26. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- Your account credentials have been saved in your Let's Encrypt
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Let's
Encrypt so making regular backups of this folder is ideal.
You’ll notice it said your certificates were saved in /etc/letsencrypt/live/discourse.example.com
. This means our Nginx config is now valid. You’ll also notice that expiration date isn’t too far away. This is normal with Let’s Encrypt certificates. All you have to do to renew is run that exact same command again, but logging in every 90 days isn’t fun, so we’ll automate it in our next step.
Now that we’ve set up our certificates for the first time, we should make sure they renew automatically. Let’s Encrypt certificates are only valid for 90 days, after which they will expire and display a warning to all visitors to your site in the browser. At the time of writing auto-renewal is not built into the client, but we can set up a script to manually renew them.
Refer to the Set Up Auto Renewal step of How To Secure Nginx with Let’s Encrypt on Ubuntu 14.04 for details on setting up a cron job to renew your certificate automatically.
Any output created by this command will be at /var/log/certificate-renewal.log
for troubleshooting.
Finally, our configuration should be complete. Restart Nginx by running this command:
- sudo service nginx restart
Now if you browse to https://discourse.example.com/
your website should be online and secured with Let’s Encrypt, shown as a green lock in most browsers.
That’s it! You now have a Discourse forum set up behind Nginx, secured with the latest SSL standards with Let’s Encrypt.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
One of our users reported the following:
I had to comment out the default HTTPS port in
app.yml
to get this to work:Otherwise, it would try to start app and listen on 443, which was already in use by nginx.
It’s all working now - any reason I should feel wary about this fix?
Working with the comments, I’ve managed to get the SSL. However, I’m looking to utilize my primary domain for a landing page and have been reading up on nginx. Given that discourse runs a proxy_pass, I was wondering how I would go about having my primary domain (eg. if forum.mydomain.com was for discourse, I’m looking to use mydomain.com) load an html file from the /var/www/html folder.
you should add to this tutorial a couple things:
1.> you’ll want to add proxy headers to your nginx config so that discourse reports the correct IP last seen (else you get 127.0.0.1):
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2.> in the section with the proxy redirect, you need to add a trailing slash, else some pages in discourse produce or try navigating to an errant URL. it should appear as such:
that is all.
Attempting to run the certificate creation I get the following:
I have commented out the
ssl_certificate
andssl_certificate_key
lines, but still have this issue, whether nginx is started or stopped. Can you give any clarification on what might be going wrong?This comment has been deleted
I followed the tutorial, but when I signup a new account, the site doesn’t respond as it opens > “https://meta.website.com:25654/…” , The user however gets registered. Its not redirecting properly. Any solution?
I think the
proxy_redirect
should have a trailing slash on the destination URL. I was having problems with malformed URLs until I added that.Hi dears, unfortunately, my website http://specknz.me/ which is based on Discourse, doesn’t loaded and I don’t really know what has caused it. I’ve got a message through a support ticket:
"Sorry to hear that you are experiencing issues with this. After reviewing this I can see that your Droplet is online and listening for http traffic. In fact when you browser to your public IP it is attempting to resolve content from your web server. It seems that once it does resolve it is resolving to a blank screen. This is typically an indicator that there was a error related to the web application.
For more information on how to resolve this issue you will want to review your nginx error and access logs. These are typically located here:
/var/log/nginx/access.log /var/log/nginx/error.log "
Then I’ve been checking these folders and they don’t exist for any reason.
Couldn’t generate a certificate and have got a bunch of errors. Can be it caused by the using a $5 Droplet and SWAP?