Deploy Ghost Blog on Ubuntu Server and serve it to subdirectory using Nginx

We're going to walk through how we installed and deployed a Ghost blog on our Ubuntu server and served it as a subdirectory using Nginx.

We are running Ghost as our blogging platform because all of our devs love Javascript, but also we needed something that isn't too code intensive like Octopress because half of our company are people who don't write code.

Getting Ghost onto a server isn't too bad, but there are a few tricks especially since we wanted it to be served to the same domain as our website built in Ruby, but under a different subdirectory.

First you need to get Node.js installed on your server:

Install NodeJS

sudo apt-get install python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs

Install Ghost

We're going to jump into the directory where we keep all of our website source code and install Ghost:

cd /var/www/
sudo wget
sudo apt-get install unzip
sudo unzip -d ghost
cd ghost/
sudo npm install --production

Configure Ghost

Now it's time to configure a bunch of things so that Ghost is setup the way we need it.

Before you get started, I recommend going over to and getting an account. We'll use Mandrill to send all mail for the blog.

We're going to copy over the example config file and then edit it from there.

sudo cp config.example.js config.js
sudo vim config.js

In the production section of the config file you're going to change a few settings:


url: '',

to your url:

url: '

host: '',


host: '',

And finally you're going to change the mailer

mail: {},


mail: {
        transport: 'SMTP',
        host: '',
        options: {
            service: 'Mandrill',
            auth: {
                user: 'Mandrill Username',
                pass: 'Mandrill API Key',

Create Ghost User and Test

sudo adduser --shell /bin/bash --gecos 'Ghost application' ghost
sudo chown -R ghost:ghost /var/www/ghost/
su - ghost
cd /var/www/ghost/
npm start --production

You should see a message that "Ghost is running." If you see this then SUCCESS! You can test it at:


CTRL+C will exit you out of that process and back into the bash prompt.

Run Ghost as background process

Now you just got Ghost running but if you exit the terminal then you'll kill the process. We need it to run constantly in the background as a process. For that we use Forever.

Switch back to your deployment user with exit

Now install Forever:

sudo npm install -g forever

From within the Ghost directory you can now start it up:

NODE_ENV=production forever start index.js

You should see a success message. Now Ghost is running in production.

Configure Nginx to listen to Ghost port and serve it as a subdirectory of existing site

This one is actually pretty easy. Our original site that we were serving this website under is and we want to serve the blog at but they're two completely different applications.

We use one Nginx config file since it's all for the same domain, site, and port and just add location and port details. You can see below that we set the root location to a Passenger served Sinatra (Ruby) site and the /blog to proxy to the port that Ghost sits on default: 2368

server {
    listen      80;
    server_name localhost;

    location / {
        root /var/www/codelitt/current/public;
          passenger_enabled on;

    location ^~ /blog {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_redirect off;

Now just restart Nginx and you're on your way!

sudo /etc/init.d/nginx restart

All set! Check on your and you should see it there!


Download our Incubator Resources



We’re known for sharing everything!


Save more time, get more done!


Innovate from the inside

Written by
Cody Littlewood 22 Apr 2014



comments powered by Disqus