How To Serve Multiple Ghost Blogs on One VPS Using Nginx Server Blocks

Published on October 21, 2013
How To Serve Multiple Ghost Blogs on One VPS Using Nginx Server Blocks


Ghost is a great new blogging platform that simplifies the process of getting a blog up and running. It boasts a clean interface and an easy-to-use interface.

In this article, we will discuss a method of using one VPS to host multiple blogs. We will be configuring two domain names that will resolve to different instances of Ghost being hosted on the same system.


This guide assumes that you are starting on a fresh droplet that was configured with the one-click Ghost image. For instructions on how to spin up a Ghost blog on DigitalOcean, click here.

This also assumes that you have two separate domain names that you will be using for each of your blogs. They both should be pointed at your VPS instance that you created for your Ghost blog. To learn how to configure your domain names correctly, click here.

Finally, we assume that you are logged into your Ghost droplet as root.

Stop Running Services

Before we begin, we should stop the Ghost service to avoid problems down the line:

service ghost stop

This will ensure that we aren’t moving files that are opened by the Ghost process.

We want to do the same with nginx, just to be safe:

service nginx stop

Modify the Nginx Configuration

The first thing we need to do is adjust the nginx configuration. At the moment, nginx (our web server) is configured to pass all requests to a single location. We need to create different paths depending on what site our visitors are trying to reach.

Begin by navigating to the nginx directory where Ghost is configured. We will rename the Ghost configuration file to describe our first domain, and then copy it to a file that represents our second domain. These names are only for our reference, so you can change them as you’d like:

cd /etc/nginx/sites-enabled
mv ghost firstsite.conf
cp firstsite.conf secondsite.conf

Open the first site’s configuration with the editor of your choice:

nano firstsite.conf

Change the server_name parameter to match your first site’s domain name. It is important to get this part right, because it is the only way that nginx will know which Ghost instance to pass control to.

server_name firstsite.com

Save and close the file.

Next, we need to perform a similar operation on our second site configuration. Open it with your text editor:

nano secondsite.conf

We need to change the server_name parameter again to match our second site’s domain name. Again, make sure this is accurate:

server_name secondsite.com

We also need to change the port that should be used for our second site. Right now, this configuration would send all of the traffic to the same node.js instance, instead of splitting it between the two sites.

Change the proxy_pass parameter. We need to change the port number at the end to another number. It can be any port number that isn’t being used by another process.

proxy_pass http://localhost:2777

Save and close the file.

Restart nginx by typing:

service nginx restart

Change the Ghost Configuration

Now, we need to mirror our changes in the Ghost configuration files. Go to the web root directory:

cd /var/www

We need to make a directory for each of our Ghost sites:

mkdir firstsite.com
mkdir secondsite.com

Now, we need to move the Ghost directory into each of the new folders:

cp -r ghost firstsite.com
mv ghost secondsite.com

Now, we can open the first site’s Ghost configuration:

nano /var/www/firstsite.com/ghost/config.js

Find the production section by searching for the string production: {. Change the url parameter to match the name of your first site:

. . .
production: {
    url: 'http://firstsite.com'
. . .

Save and close the file.

Next, open the matching file for the second site:

nano /var/www/secondsite.com/ghost/config.js

Again, find the production: { section. Change the url parameter to match the second site’s domain:

. . .
production: {
    url: 'http://secondsite.com'
. . .

Next, scroll down a bit to the server: { section of the production block. Change the port parameter to match the number you selected for the proxy port in the second site’s nginx configuration:

port: '2777'

Save and close the file.

Create Upstart Scripts

The easiest way to manage separate Ghost installations is through Upstart scripts. This will allow you to start, stop, restart, and check the status of each site individually.

Currently, there is a System V init script located at /etc/init.d/ghost. If you are following this guide, delete the old System V script. This will help avoid confusion and can prevent the service starting with the wrong settings:

rm /etc/init.d/ghost

We will be creating a new configuration for each site. We will be using an alternative to System V called Upstart, because it has a simpler syntax.

Change to the directory where Upstart keeps its scripts:

cd /etc/init

Create a file for your first site:

nano ghost-firstsite.conf

Inside, we will place the following code. Change the values in red to match your first site’s configuration:

# ghost-firstsite

start on startup

    cd /var/www/firstsite.com/ghost
    npm start --production
end script

Save and close the file.

We will create the second site’s configuration file by copying the one we just created:

cp ghost-firstsite.conf ghost-secondsite.conf

Open the new file and adjust the values in red to match the second site:

# ghost-secondsite

start on startup

    cd /var/www/secondsite.com/ghost
    npm start --production
end script

Save and close the file.

Now, you can bring each site online by typing:

service ghost-firstsite start
service ghost-secondsite start

If you visit each of your domains, you should see the Ghost blogging landing page.

Ghost landing page

Create your user account and log in by visiting:


Add different content to each site to verify that they are truly separate.

Ghost first site

Ghost second site


You should now have two separate blogs being served from a single droplet. You can expand this technique to serve additional sites, as your resources permit.

Check out our other articles to learn how to change themes and settings, how to configure email and test configuration changes, and how to manage content.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

I just removed

    listen [::]:80 default_server ipv6only=on;```
from one of the conf files and it works.

having problems running mv ghost firstsite.conf because sites-enabled only has default shortcut no ghost

although sites-available does have default and ghost Also rm /etc/init.d/ghost wouldn’t run either since there was no ghost file at that directory either

update: I just copied the ghost file from available-sites dir and copied it to enabled-sites, however now when i run service ghost-firstsite start, i get the error:Failed to start ghost-firstsite.service: Unit ghost-firstsite.service not found

This tutorial is out of date and needs to be edited.

  1. sites-enabled is empty.
  2. System V is not present
Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
December 5, 2013

@cody: Edit seconddomain.com’s nginx config and set server_name to the following: <pre>server_name seconddomain.com www.seconddomain.com</pre>

Hi there, are these above instructions still workable in 2021 with the latest versions of ghost?

Is this page (or even multiple) broken?

Some code is with <pre> in front of it and the layout is broken

Hey, this post needs a Deprecation notice as the method doesn’t work in ghost v2 where we need database. It sure worked with ghost v1 where websites were static. Let’s add it? :)

when i try the command as root service ghost stop i get the error Failed to stop ghost.service: Unit ghost.service not loaded.

When i try as ghost-mgr it asks for a password. What is the password the digital ocean creates for ghost-mgr account by default? The one for my root account doesn’t work.

How do I find the current services of the new domains? Maybe that way I can troubleshoot it

Failed to start ghost-blog.service: Unit ghost-blog.service not found.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel