Install Ghost on Debian + Apache

Ghost is a simple, powerful publishing platform that allows you to share your stories with the world.

Despite the amount of information available online, I spent hours trying to setup the very same blog you are reading right now. I'll try to make it easier for you by telling you exactly how I finally succeeded.

This is not a perfect guide, I'm not an expert, I'm just sharing what worked for me. If you find something that could be perfected, please let me know.

Edit (2015-08-03): Totally forgot to talk about forever. This is now fixed. Thanks to BadAtParties on the Reddit thread.


At the time of writing, Debian's latest stable version is 8.11 « jessie », Apache's current version is 2.4.102 and Ghost's latest github release is 0.6.4. If you're using anything else I can't predict the results.

Warning: I won't write sudo all the time, I assume you have the correct permissions. Also, Don't forget to replace youruser, yourserver and so on.

The very first thing you should do is to create a DNS entry for your blog, to make your domain or subdomain point to your server's IP. This is usually done via your domain registrar's interface, and depending on your registrar it could take from few minutes to several days (which is a good sign to change for a better one).

Once it's done, fire up your favourite terminal3 and copypaste the following:

# Login to your server via SSH
ssh youruser@yourserver.tld

# Download the latest updates
apt-get update

# Install/update node (and npm)
apt-get install nodejs  


Apache setup

I use VirtualHosts, I assume you do too.
If you don't there are countless very good tutorials available.

# Go to Apache VirtualHosts' config folder
cd /etc/apache2/sites-available

# Create a .conf file for your Ghost blog
nano ghost.yourserver.tld.conf  

Yes, I'm using nano. It's awesome. Write this:

<VirtualHost *:80>  
    ServerName ghost.yourserver.tld
    ProxyPreserveHost On
    ProxyPass /

Ctrl + O to save, Enter to confirm, Ctrl + X to quit.
And finally, enable your new VHost:

a2ensite ghost.yourserver.tld.conf  
service apache2 reload  

The following is optional.
I tried a lot of things when I couldn't get it to work, including this, so I don't know if it did anything or not. If you're stuck, try it, but avoid it if you can.

# Open the default port used by Ghost (2368)
iptables -I INPUT 1 -p tcp --dport 2368 -j ACCEPT  
iptables save  

Spooky ghost

Ghost setup

Go to the directory where you want to install Ghost, create it if need be.

mkdir /your/path && cd $_  

Now is the time to find out if you're lucky. There are 3 options available, if you're lucky all you will need is a one-liner.

1. First, try this:

npm install ghost --production  

Edit Ghost's config with your blog's URL

nano config.js  

Hit Ctrl + W to prompt the Search function, type my-ghost-blog and hit Enter.

nano will jump to the relevant position in the file, find and replace with ghost.yourserver.tld (and https with http if relevant).

Let's try to start Ghost:

npm start --production  

Open a web browser, cross your fingers and go to ghost.yourserver.tld.
If you see Ghost's welcome page you're good to go.

2. Second chance

If it did not work, rm -Rf everything in the directory and try the following:

# Download Ghost's latest version from

# Unzip it in your directory

# Remove the zip file

# Install Ghost
npm install --production  

And then try again to start Ghost.

3. Third time's the charm

We've tried the shortcuts, but sometimes it just won't work. Fortunately this last option was the solution for me. We'll be doing what the documentation refers to as Developer install. It's not lean, it's slow, but at this point I bet you're willing to resort to anything.

Install/update dependencies

You will get Ghost's latest version from Github with git and build some stuff with make, which is part of Debian's build-essentials package. Grunt is used as well, and must be installed globally.

apt-get install git build-essentials  
npm install -g grunt-cli  

Once again, start by rm -Rfing the folder, and then build and install Ghost:

# Clone Ghost's latest version from Github
git clone git://

# Go to the directory and checkout the stable version
cd ghost && git checkout stable

# Proceed to the installation
npm install

# Build with grunt, takes a while
grunt init

# Minify things for production
grunt prod  

And finally, try one last time.

Failure is an option.

Nothing worked

If at this point it doesn't work, I'm afraid there's nothing else I can do for you. Sometimes things suck. Try reloading apache, check if your port is open from antoher Terminal, check your DNS, ping your (sub)domain. Hit StackOverflow maybe. Sorry.

One last step

Nothing is forever, then what makes Ghost the exception?

We finally have our Ghost blog up and running, but as soon as we hit Ctrl + C to go back to the shell, the blog is offline. We have to use some tool to keep it running all the time, there are many options, my favourite is forever.

# Install forever 
npm install forever -g

# Start Ghost using forever from the Ghost installation directory
NODE_ENV=production forever start index.js

To check if Ghost is currently running type forever list, to stop Ghost type forever stop index.js.

Side note: I've been using forever for a long time, and there's a feature I love, which is the --watch, aka -w option. It tells forever to watch Ghost's files all the time and restart automatically if it detects any change. This is perfect for updates, or on a development environment, but I don't know if it would be a good thing on a production server. If you've tried, please advise.

You may wish to start forever at boot, I recommend this method.

Hold a kitty

What to do next

If you reached this point Ghost is installed and the fun begins.
Go to ghost.yourserver.tld/ghost and follow the instructions.

This is where I leave you.
Hope you liked my first post, hopefully there will be more to come.


  1. "Finding your Debian [...] install version" — Wilson Software

  2. "Find out Apache version" — nixCraft

  3. I use Git Bash on Windows, Terminal w/ Oh My Zsh on MacOs, Debian's bash on Debian