Host Multiple Ghost Blogs on a Single VPS

Ghost is an excellent blogging platform that can easily be setup on a VPS in minutes. Even the smallest VPS is more than powerful enough to support multiple blogs of a typical user. Unfortunately, Ghost does not support multiple blogs in a single instance, but using Nginx we can setup multiple instances on a single VPS. In this guide, we'll be using DigitalOcean as the VPS provider, though using Amazon EC2 or other should be similar. This also means we'll be using Ubuntu as the OS, and Nginx as the web server. First we'll configure web access with Nginx and then we'll setup two different ghost installs. The only prerequisite is having two separate domain names ready to use.

Nginx Configuration

Nginx is the key to supporting multiple Ghost blogs, and you should be using it even if you only have one blog. If you don't already have Nginx, install with:

sudo apt-get update
sudo apt-get install nginx

By default, Ghost runs on port 2368. In order to access your site in a browser, Ghost needs to run on port 80 (that is, unless you want to force users to append :2368 to your site). You have the option to configure Ghost in the config.js file to run on port 80, but then you also must run Ghost as the root user, leaving your site more vulnerable.

Nginx provides a reverse proxy that allows us to separate the web request port and the Ghost port. This means I can leave Ghost running on port 2368, and have Nginx route all requests from port 80 to port 2368. Even better, I can configure Nginx to listen for a domain name in each request, and forward each to different ports. This solves both the security problem and hosting two blogs on the same port.

To configure Nginx, we will navigate to the config directory and rename the default configuration to that of our first site:

cd /etc/nginx/sites-enabled
mv ghost myfirstghost.conf

Now, open up the default configuration:

nano myfirstghost.conf

Now, if you have already setup one ghost blog, there shouldn't be anything to change. Just make sure that the server_name is filled with the url of the first site:

server_name myfirstghost.com www.myfirstghost.com;

Also, take note of the port number listed after proxy_pass http://localhost:2368 I expect it to be the default of 2368, but if not, write it down. If it is port 80, change it to some four digit number.

Save and close the file with Ctrl-x and hit Y and then Enter. Now we need to copy the config file for the second site:

cp myfirstghost.conf mysecondghost.conf

Open up mysecondghost.conf with nano or another text editor

nano mysecondghost.conf

You'll notice at the top of the file some code that defines port 80 as the listening port. Nginx will combine both site configuration files, making this code redundant, which could cause errors if not removed. So *remove * the following lines (only from the mysecondghost.conf!):

listen 80 default_server;
listen [::]:80 default_server ipv6only=on;

Moving on, modify the server_name with the url of your second site:

server_name mysecondghost.com www.mysecondghost.com;

Now, scroll down to the proxy_pass http://localhost:2368 and change the port number to another 4 digit number. I would avoid 2369, since this is used for development environment of Ghost. I'll choose 2468 as my port. We are now done with the Nginx setup. Go ahead and restart Nginx:

service nginx restart

Ghost Configuration

In Linux, you most likely will store your ghost websites in /var/www directory. Go to that directory with cd /var/www and create two folders that will host two separate installs of ghost (obviously naming each appropriately) :

mkdir myfirstghost
mkdir mysecondghost

If you already have a single ghost install under /var/www go ahead and copy it into the first site folder.

cp -r ghost myfirstghost

If you don't have a Ghost install setup, see the Ghost guide here first. Then move the remaining copy into the empty folder for the second site:

mv ghost mysecondghost

Let's start with the configuration of the first site. Navigate to the main ghost directory under the first site:

cd /var/www/myfirstghost/ghost

Now, open the config.js file that holds the Ghost configuration:

nano config.js

We need to ensure both the url and port number are correct. For the first site, the port number is 2368 - the default - or whatever you entered in the myfirstghost.conf nginx file earlier. Make sure you edit the values in the production section.

config = {
// ### Production
// When running Ghost in the wild, use the production environment
// Configure your URL and mail settings here
production: {
    url: 'http://myfirstghost.com',
    mail: {},
    database: {
        client: 'sqlite3',
        connection: {
            filename: path.join(__dirname, '/content/data/ghost.db')
        },
        debug: false
    },

    server: {
        // Host to be passed to node's `net.Server#listen()`
        host: '127.0.0.1',
        // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
        port: '2368'
    }
},

Save and close the file and let's move to our second Ghost install:

cd /var/www/mysecondghost/ghost
nano config.js

Again, change the url to that of your second site and the port value to the one used in mysecondghost.conf nginx config - for this guide, I used 2468. Configuration of the Ghost blogs is now complete!

Keep Ghost Running

With the npm start syntax, your blog will only run while the console is open. To run Ghost continually as a service, we need another solution. PM2 is regarded as one of the better ways to do this. So to keep this post complete and get both blogs up and running, we'll walk through how to do this.

Install PM2 with:

npm install pm2 -g

Navigate to the Ghost root directory for each Ghost install:

cd /var/www/myfirstghost/ghost
NODE_ENV=production pm2 start index.js --name "myfirstghost"

Now you can start both blogs by typing:

pm2 start myfirstghost
pm2 start mysecondghost

Wrap Up

You should now have two blogs configured on a single VPS. Try visiting both urls to confirm both are active. Since we copied the blogs, we need to ensure that they are truly separate. Make some edits and confirm that each url is pointing to a different Ghost instance. Using this method, you can easily expand to many more blogs as long as your VPS can support it.

Brandon Brown

Read more posts by this author.