Install Ghost on Debian + Apache

Jan 24, 2018 · 5 min read

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 my previous blog. 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.1 « jessie », Apache’s current version is 2.4.10 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 terminal 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

NB: Your Apache setup may require “a2enmod proxy” before restarting Apache. (thanks Dan Hetherington)

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

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 (see above).

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.

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.

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


Stuff I wish had been on top of Google results when I was…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store