Obviously, as a responsible sys admin about town, you're using SSL already. But on the off chance you're not, what are your options?

I wanted to get SSL setup on this here, self hosted, Ghost-based blog. This was mostly as a learning exercise, and in the spirit of best practice, rather than due to data concerns for the traffic on this site. I'm not exactly asking for bank details here.

After a less than positive experience dealing with a CA at my workplace, I decided to have a proper look at Let's Encrypt, a free Certificate Authority gaining heavy traction on the web. Security is a big deal on the web, so for the curious and/or concerned, I recommend reading their About page, and browsing the project code on Github.

Happy with that? Excellent. Now, let's encrypt Ghost!

Table of Contents
  1. My Setup
  2. Get the code
  3. Memory issue
  4. Obtain certificates
  5. Configure site
  6. Redirect traffic
  7. Restart your site
My setup

Here's what I'm using:

Get the code

Access your server:

$ ssh me@myserver

Download the code:

$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt

Run the setup script. The script will prompt for root authentication:

$ ./letsencrypt-auto
Memory issue

That should be all you need to do. However, I had issues with the setup script crashing out. I received the error you can see here. I then ran the following for more verbose output:

$ ./letsencrypt-auto -v -h

That produced this at the point of failure:

error: command 'x86_64-linux-gnu-gcc' failed with exit status 4

and the following output to dmesg:

$ dmesg | tail
[3561137.965737] Out of memory: Kill process 30872 (cc1) score 310 or sacrifice child
[3561137.967860] Killed process 30872 (cc1) total-vm:302940kB, anon-rss:154988kB, file-rss:0kB

Stack Overflow to the rescue. My VPS was running out of memory, so I created a swap file as follows:

$ dd if=/dev/zero of=/swapfile bs=1024 count=524288
$ chmod 600 /swapfile
$ mkswap /swapfile
$ swapon /swapfile

And then ran the setup again:

$ ./letsencrypt-auto -v -h


Obtain certificates

First, stop Nginx:

$ systemctl stop nginx

Let's Encrypt doesn't yet contain plugins for Nginx, so I'm using the 'standalone' option.

$ ./letsencrypt-auto certonly --standalone

You'll be prompted to answer some basic questions. Once complete, you're certificates will be saved to:


Let's Encrypt certificates are valid for 90 days. Set yourself a calendar reminder to renew.

Configure site

Configure your site.conf file:

$ vim /etc/nginx/conf.d/ghost.conf

Modify the file as follows:

server {
    listen 80;
    listen 443 ssl;
    server_name your_domain_here;
    ssl_certificate     /etc/letsencrypt/live/your_domain_here/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain_here/privkey.pem;
    access_log /var/log/nginx/your_domain_here.log;
Redirect traffic

You'll want to redirect all traffic to your site to port 443. You need to add some further config to /etc/nginx/conf.d/ghost.conf as well as modifying your Ghost site config.js.

Edit ghost.conf

$ vim /etc/nginx/conf.d/nginx.conf

Add the following below the existing server block:

location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;

Now modify your config.js:

$ vim /var/www/ghost/config.js

Change all instances of your site url from http to https.

Restart your site

Restart Nginx:

$ systemctl start nginx

And restart your NPM based Ghost install. I use the Forever package, and so used the following command:

$ forever restart /var/www/ghost/index.js

You should now be able to browse explicitly to:




The latter should automatically redirect to the SSL-enabled site, which you can verify with the padlock icon in your browser address bar.

You, and those visiting your site, are now safe(r) from the boogie men of the internet, and you can sit back safe in the knowledge that you've done the right thing.

Have a secure 2016!