[Ghost] Enable SSL in Apache

This article explains how to add HTTPS support for your Ghost blog. You can choose to allow both HTTP and HTTPS, or only HTTPS.

I assume that you followed the instructions of my article “Install Ghost along with Apache”. I also assume that you have generated a SSL certificate (see Requirements bellow)

This has been successfully tested on Ubuntu 14.04.1.

Requirements

  1. Apache and Ghost working properly in HTTP
  2. Your certificate file, with the extension .crt
  3. Your private key file, with the extension .key
  4. The intermediate certificate of the CA, with the extension .pem

Step 1: Configure Apache

You first need to enable the ssl and headers modules:

a2enmod ssl
a2enmod headers
service apache2 restart

Then edit /etc/apache2/sites-available/ghost.conf and append:

<Virtualhost *:443>
  ServerName       example.com
  ServerAdmin      [email protected]
  ProxyPass        /  http://localhost:2368/
  ProxyPassReverse /  http://localhost:2368/
  ProxyPreserveHost   On
  SSLEngine           On
  SSLCertificateFile     /etc/ssl/certs/example.com.crt
  SSLCertificateKeyFile  /etc/ssl/private/example.com.key
  SSLCACertificateFile   /etc/ssl/certs/Xxxxxxx.pem
  RequestHeader set X-Forwarded-Proto "https"
</Virtualhost>

Don’t forget to replace example.com with the actual URL of your blog, and the certificate files with the real ones.

When it’s done:

service apache2 reload

Why the X-Forwarded-Proto header?

If you don’t add this header, Ghost would not know when your blog is served via HTTPS and it would assumes it’s plain HTTP.

Therefore, when Ghost enforces a HTTPS connection, it would redirect the browser to https://.... But this is the same address and Ghost still believes it’s HTTP, so it would redirect again…

And it would do this in an infinite loop. Eventually the browse would issue an ERR_TOO_MANY_REDIRECTS.

Step 2: Configure Ghost

Edit /var/www/ghost/config.js to add urlSSL and forceAdminSSL to the production environment:

production: {
    url: 'http://example.com',
    urlSSL: 'https://example.com',
    forceAdminSSL: true,

Restart Ghost:

service ghost stop

cd /var/www/ghost
npm install --production

service ghost start

That’s it!

You should now be able to open your blog in both HTTP and HTTPS. The administration part will be strictly served via HTTPS.

Want to force HTTPS for the whole site?

Just edit config.js and put https://... in the url field.

That way Ghost knows that the site must be served via HTTPS only and will send a redirection if someone tries to load a page in HTTP.

You don’t need to configure the redirection in Apache, Ghost will take care of it.

References