Running multiple Ghost blogs on a VPS

This is a continuation of my previous post Installing Ghost on Ubuntu 14.04

Ghost doesn't natively support a multi-site setup in the same manner as WordPress so there is a little more setup involved. There are 4 main steps to setting up an additional blog on your VPS:

  1. Get your new blog code onto the server
  2. Configure the new blog
  3. Use PM2 to manage the new blog's ghost process
  4. Add a new Nginx server block (virtual host)

Get the blog code

The first issue I ran into was that deploy keys cannot be re-used on GitHub so having two repositories that are deployed to the same server proved to be a problem. To workaround this I created a "machine user" as detailed in GitHub's Managing deploy keys guide.

As I'm using git for this new blog, the process is the same as outlined in the server setup post. Log in as your sudo enabled user and run the following:

cd /var/www
sudo git clone git@github.com:my-account/my-new-blog.git
cd my-new-blog
sudo npm install --production
sudo chown -R ghost:ghost /var/www/my-new-blog/

Configure the blog

Because we already have one blog running on the default Ghost port it's necessary to make some changes to the new blogs config before we can continue. Log in as your 'ghost' user and edit the config:

cp /var/www/my-new-blog/config.example.js /var/www/my-new-blog/config.js
nano /var/www/my-new-blog/config.js

In the config file, change the production URL to match your site:

url: 'http://my-new-blog.com',

And make sure to change the server port to an unused port number:

port: '2468'

Here, I have just bumped the port number up by 100 from the default value. Make a note of the port number as you will need it when we get to the Nginx configuration.

Manage ghost process with PM2

As per our previous blog, we'll be using PM2 for the process management. First, as the 'ghost' user, run the following:

cd /var/www/my-new-blog
pm2 start index.js --name my-new-blog

That's all the setup that is needed. We have already installed PM2's init scripts in the server setup so there's nothing else to do now.

You may notice that our new ghost application instance has a more meaningful name than our previous instance which is just called 'ghost'. If you would like to rename it so you don't need to remember which blog 'ghost' refers to, run the following:

cd /var/www/my-blog
pm2 delete ghost
pm2 start index.js --name my-blog

Then try loading your original blog to make sure it's still up and running.

Adding an Nginx server block

Now to the last step where we make our blog accessible to the outside world. Log in to the server with your sudo-enabled user:

ssh kevin@ghost.my-blog.co.uk

NB. I'm using the 'ghost' subdomain rather than the base domain as I'm using CloudFlare as a CDN and it's necessary to bypass that to get direct access to the server

Create the config file for the new site:

sudo nano /etc/nginx/sites-available/my-second-blog.co.uk

And enter the server blog config details:

server {
  listen 80;
  server_name my-second-blog.com www.my-second-blog.com;
  location / {
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host      $http_host;
    proxy_pass         http://127.0.0.1:2468;
  }
}

Note that we have set the port in the proxy_pass setting to that which we configured earlier.

Final step, activate the site and restart Nginx for the changes to take effect:

sudo ln -s /etc/nginx/sites-available/my-second-blog.com /etc/nginx/sites-enabled/
sudo service nginx restart
Mastodon