Ghost on Ubuntu 17.04, SSL and Apache

Assumptions

This guide is for setting up a poduction version of Ghost on a VPS, it is not a guide for running Ghost locally or within a development environment.

Pre reqs:

Virtual hosts:

https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-virtual-hosts-on-ubuntu-16-04

SSL:

https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04

Install Node/Ghost

It is assumed that NVM is not managing the node install on this server

Add the node 6 repository (current LTS version)

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash

Install node

sudo apt-get install -y nodejs

Install ghost-cli, -g for global (important)

sudo npm i -g ghost-cli

Change directory to the virtual host set up for the blog
(e.g. /var/www/blog.domain.co.uk/)

sudo mkdir ghost
sudo chown [user]:[user] ghost/
cd ghost/
ghost install

During install a number of prompts will ask for input, most are straightforward and don't require any further explanation:

When asked for the blog domain, enter the domain you configured the virtual host for with the https protocol specified. This will tell ghost to always manage connections to the blog over https.

When asked to set up nginx, select no as we're using Apache instead.

You might see an error saying that the install couldn't complete because the MySQL server is complaining that the password generated for the ghost sql user is not adequate, you'll need to

ghost uninstall

and disable the password validation module in order to complete the install (see https://stackoverflow.com/questions/36301100/how-do-i-turn-off-the-mysql-password-validation for help on how to do this)

You won't be able to access your ghost install yet, see next section

Configuring Apache to correctly deal with ghost

You should already have Apache configured to use SSL correctly but you'll need a few more mods enabled in order to get Apache working with ghost

a2enmod proxy_http

This will install the proxy and proxyhttp mods.

a2enmod rewrite
a2enmod headers

rewrite is required for rewrite engine rules that need to be added to the virtual hosts .conf file for the domain being worked with.

headers is required to prevent an infinite loop of redirects over https connections.

Restart apache

systemctl restart apache2.service

If you've configured ssl certs for the blog domain previous to starting this guide then you'll have two .conf files for the domain you're using, one for http and one for https.

http:
Make sure that the uncommented lines are included in the .conf file and substitue domain for the FQD.

<VirtualHost *:80>
	ServerAdmin name@email.com
	ServerName blog.domain.co.uk
	#ServerAlias blog.domain.co.uk
	#DocumentRoot /var/www/blog.domain.co.uk/public_html

	#<Directory "/var/www/blog.domain.co.uk">
        #        Options FollowSymLinks
        #        AllowOverride All
        #        Order allow,deny
        #        Allow from all
    #</Directory>

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

ProxyPass / http://127.0.0.1:2368/
ProxyPassReverse / http://127.0.0.1:2368/
ProxyPreserveHost On
RewriteEngine On
RewriteOptions inherit

</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

https:

<IfModule mod_ssl.c>
<VirtualHost *:443>
	ServerAdmin name@email.com
	ServerName blog.domain.co.uk
	#ServerAlias blog.domain.co.uk
	#DocumentRoot /var/www/blog.domain.co.uk/public_html

	#<Directory "/var/www/blog.domain.co.uk">
        #        Options FollowSymLinks
        #        AllowOverride All
        #        Order allow,deny
        #        Allow from all
    #</Directory>

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

ProxyPass / http://127.0.0.1:2368/
ProxyPassReverse / http://127.0.0.1:2368/
ProxyPreserveHost On
SSLEngine On

SSLCertificateFile /etc/letsencrypt/live/blog.domain.co.uk/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/blog.domain.co.uk/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf

RequestHeader set X-Forwarded-Proto "https"

</VirtualHost>
</IfModule>

Restart apache again and try browsing to domain ghost was installed under, you should see the blog load with some dummy content.

Go to blog.domain.co.uk/ghost to set up a user immediately before doing anything else.

You now have a working install of ghost running on an apache webserver!

If you wanted to install another instance of ghost on the same server, you can repeat the above steps but make sure to change the port number that ghost listens on to something else.