Report this

What is the reason for this report?

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

Introduction


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.

Prerequisites


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

script
    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

script
    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:

firstsite.com/ghost/signup

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

Ghost first site

Ghost second site

Conclusion


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 author

Justin Ellingwood
Justin Ellingwood
Author
See author profile

Former Senior Technical Writer at DigitalOcean, specializing in DevOps topics across multiple Linux distributions, including Ubuntu 18.04, 20.04, 22.04, as well as Debian 10 and 11.

Still looking for an answer?

Was this helpful?
Leave a comment...

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!

It was all good till Restart nginx by typing: service nginx restart

Below is what I get as an error

Restarting nginx: nginx: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32 nginx: configuration file /etc/nginx/nginx.conf test failed

I fixed it, I had to increas it from nginx.conf

For me not work. This return me a 502 error and I´ve followed all as here

Followed every step in detailed. First site worked perfectly but when I visit second site, I get 502 error.

It worked for me now. I guess something was wrong with my Upstart configuration. Nevertheless,I moved into the /var/www/secondsite/ghost and npm start ! And the second site worked on a different port we mentioned in the second site nginx conf file.

Thanks for the tutorial.

Thanks @springhive for the aclaration!! Now worked!!

Will this work with subdomains as well?

For example: ghost1.mydomain.com ghost2.mydomain.com

@mike: Yes, it will work just fine.

Great, thanks Kamal.

To restart Ghost if you follow this tutorial:

service ghost-firstsite restart service ghost-secondsite restart

great read!

so after setting it up my domains seem to always redirect to /ghost/signin i can’t figure out why…

got it all working except www.seconddomain.com is redirecting to www.firstdomain.com BUT seconddomain.com without “www” goes to where it is supposed to go. Any tips?

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

I have followed the tutorial, but my ghost services don’t start - when I type in service ghost -domain start, ssh outputs:

stop: Unknown instance: ghost-domain stop/waiting

P.S. When I examined the logs of the service that I created, that’s what showed up -

“/proc/self/fd/9: 2: cd: can’t cd to /var/www/nick-s.se/ghost”.

Why can’t the script cd to my ghost folder?

@Nick: Does that directory exist? Does the user ghost have access to it?

What is the process for when you want to add ‘thirdsite.com’ and ‘fourthsite.com’ later on-- down the road? Add more server blocks, then follow steps above?

@whatspo: Correct.

sorry I have another question Kamal, Im trying to troubleshoot as I haven’t been able to get firstsite.com and secondsite.com to work as two different blogs. They are acting as one. Meaning, when I adjust content on one, the other reflects the changes. And vice versa.

So I’m thinking I might be skipping some step(s) that I don’t know about.

When I go to set up the configurations and everything listed in the tutorial above, do I need to have directories or folders already set up for each of the sites?

the advice I got from DO support was that it would all be going on ONE server block, so its getting a little confusing now…

I was finally able to get through this! All seems to be working now. Thank you for the help anyways.

For those looking to have multiple users over the same app: http://labs.djenie.com/hacking-ghost-hunting-the-evil-spirit/

Cheers!

I’ve went through the tutorial twice and I still get this error "Restarting nginx: nginx: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32 nginx: configuration file /etc/nginx/nginx.conf test failed "

I went into the /etc/nginx/nginx.conf file and increased the size, but the server still will not start?

Can you do this with the same domain, just different beginnings, like www.domain.com and test.domain.com?

I take it this is out of date now, the line proxy_pass http://localhost:2777 does not exist in the nginx conf file.

@WW2Net: This tutorial assumes that you are using the DigitalOcean Ghost application as your starting point. That line exists there. See this article to get up and running:

https://www.digitalocean.com/community/articles/how-to-use-the-digitalocean-ghost-application

Ok, I had a single site up and running using the DigitalOcean Ghost application, then followed this tutorial to move the site and set up a second site. Now, though, when I try to access the first site, I get an error 500:

500

SQLITE_CANTOPEN: unable to open database file, sql: select “posts”.* from “posts” where “page” = ? and “status” = ? order by “status” collate nocase ASC, “published_at” collate nocase DESC, “updated_at” collate nocase DESC limit 7 offset 0, bindings: false,published

Ok, first site is working. Power cycled the droplet, and now is working.

Thank You.

Though everything looks cool but there is a problem i am facing . Yesterday i restarted my VPS for backup issue , Ghost didn’t started in one domain. I have two domain running Ghost. One started Ok but other didn’t , why is that ? Do i need to delay the script ? Please help.

@obak: First make sure that when you copied “ghost-firstsite.conf” to "ghost-secondsite.conf "you changed all instances of “ghost-firstsite” to “ghost-secondsite” If that wasn’t the issue, try to start the one that didn’t come up on its own and see if there are any error messages:

<pre> service ghost-secondsite start </pre>

any pointers if I’m trying to set up a ghost blog and a static site ?

@rrrrrraul: That would be much easier. You’d just need a new server block with the domain name of the static site. This should point you in the right direction:

https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-virtual-hosts-server-blocks-on-ubuntu-12-04-lts--3

i failed. it only show welcome to nginx

@rufranop: Yes, just make sure the port you’re choosing is unused:

sudo netstat -plutn | grep :port-number

If there’s no output, the port is free.

Ghost 0.5 has finally arrived and the question is…How do we upgrade our multiple ghost blogs on one VPS?

###To upgrade your existing Ghost 0.4 install, follow these instructions:

Stop nginx and all Ghost instances:

sudo service nginx stop
sudo stop ghost-firstsite
sudo stop ghost-secondsite

Create a backup:

cd /var/www
sudo mkdir backup-pre-0.5-upgrade
sudo mv ghost-latest.zip backup-pre-0.5-upgrade
sudo cp -r firstsite.com backup
sudo cp -r secondsite.com backup

Install the latest Ghost release:

cd /var/www
sudo wget http://ghost.org/zip/ghost-latest.zip
sudo rm -rf firstsite.com/ghost/core
sudo rm -rf secondsite.com/ghost/core
sudo unzip -uo ghost-latest.zip firstsite.com/ghost
sudo unzip -uo ghost-latest.zip secondsite.com/ghost
cd /var/www/firstsite.com/ghost
sudo npm install --production
cd /var/www/secondsite.com/ghost
sudo npm install --production
sudo chown -R ghost:ghost /var/www/firstsite.com/ghost/*
sudo chown -R ghost:ghost /var/www/secondsite.com/ghost/*

Start Ghost and nginx:

sudo service nginx start
sudo start ghost-firstsite
sudo start ghost-secondsite

I tried to follow this as best to my ability. I installed a droplet 14.04 ubuntu with ghost but with the first step

mv default.conf firstsite.conf
cp firstsite.conf secondsite.conf

I didn’t have any files in conf.d but did have some in sites-available ghost seemed like the file to change. So I did as the tutorial showed but at the end when I try to start I’m getting “This webpage is not available” in the browser. When I ping the site I do get results.

Any suggestions on how I should continue? I can undo all the steps I did & get the site back up but I’d be a shame if I can’t put up more than one site on a droplet.

I set up a new droplet and redirected the domains to the correct droplet. After editing the proxy_pass when I try to restart nginx I get a fail response…

I just removed

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

I had the same problem Roeku had. nginx would not start until I commented out the two lines about listening on port 80 in the secondsite.conf file. Should this step be added to the tutorial?

A note for anyone finding this now: Nginx’s conf files are now kept in /etc/nginx/conf.d/, not in sites-enabled.

hi on a faq appears bad writted… ghost-<span class=“highlight”>secondsite</span> and others please can you correct?

Hi, first intsnance works well, but second always appears 502, I try many times and always the same 502

can you help me?

I followed the instructions until I needed to restart nginx. it failed and this is what I got when I ran nginx -t : nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/portfolio.conf:2

is there any way to resolve this?

So I followed this tutorial and it worked then I went back a week later to install two more installs of ghost and now i get a 502 bad gateway when I try to navigate to these sites. how can i fix the 502 bad gateway?

What happens when the sites are not truly separated and mirror content? what should i do?

I’m puzzled with the addressing. So I configured my hostnames to use the digitalocean nameservers and I added an ‘A’ record for each ‘my-domain.com’ name pointing the my droplet IP. Sounds right, right?

I also removed the ‘default_server’ parameter that others have been having a problem with, and the traffic to my_domain1.com (the default) is routing fine, but I still get and error in the nginx error log: duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/my-domain.conf:3

and I still can’t pull up my-domain2.com or my-domain3.com

and I also noticed sth else.

If i ‘ls -la’ the contents of /etc/nginx/sites-enabled/ i can see the default ghost file (before renaming it) is actually a symlink to /etc/nginx/sites-available/ghost

Should we not mimic the structure by putting the new hostname files in /nginx/sites-available and creating the requisite symlinks in /nginx/sites-enabled?

Sorry if it’s a n00b question, I’m new at this.

I’ve followed all the steps, and everything looks like it works correctly. Wasn’t it that both are sharing all content and all data of the ghost blog. So it means they do not act as two separate blogs. What could be the reason?

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.