Adding SSL to Ghost on DigitalOcean

in code

This morning I went through the unexpectedly pleasant experience of adding an SSL certification to this site. Turned out to be much easier than I planned on, and there was only one small hiccup I was able to resolve quickly.

I opted to go with a free Let's Encrypt SSL/TLS Certificate and use the automated installation from certbot. The certbot instructions were straightforward and only took a few minutes to complete, but did result in one issue, so here's a quick tutorial on how to add an SSL cert to your Ghost site quickly.

First, a few specifics about my current setup:

  • Ubuntu 14.04 (trusty)
  • Nginx 1.4.6
  • Ghost 0.11.10
  • Hosted on DigitalOcean

Install the necessary packages

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx 

This installs the Certbox Nginx plugin, which we then run with:

sudo certbot --nginx

Running this will issue a certificate for you and have Certbot edit your Nginx configuration automatically.

Fix the Nginx Configuration

Unfortunately for me, as I discovered the editing of my Nginx configuration was flawed and required some changes. I noticed the issue after restarting the server - resulting in a ERR_TOO_MANY_REDIRECTS error.

To fix the issue, find and open your Nginx configuration file. To find which file is being used, run:

nginx -t

This will show the location of the Nginx configuration file. This file might be, or will contain the path in an include statement to the Nginx configuration file. Open this file in a text editor.

In my case it looked like the parsing of the file had gone awry and the server block was a mix of port 80 and 443 settings.

Another fix I had to make was to add the X-Forwarded-Proto header to several of the location blocks:

proxy_set_header X-Forwarded-Proto https;

Here's the full Nginx configuration I'm using:

Setup auto-renew on the SSL

Let's Encrypt certificates last for 90 days so unless you want to go through some of the steps above you'll want to setup a cron job to auto-renew the SSL. To do this, run:

crontab -e

select your favorite editor and add the following line:

15 3 * * * /usr/bin/certbot renew --quiet --renew-hook "/usr/sbin/service nginx reload"

This sets the Certbox auto-renew script to run each day at 3:15am. Your SSL certificate will be automatically renewed and reloaded when it has thirty days or less before it's expiration date.