I had to restart everything.

You see, getting Node.js and apache to work together wasn’t going to fly, so I went and built a new VPS with Ubuntu over on DreamHost. Obviously not everyone has this luxury, but since I do, and since DreamHost made this as easy as clicking on a box, I thought it would be perfect.


You have to be shell savvy for this. Sorry. There’s no other way. Just accept that and move on.

You need a VPS. The new Ubuntu SSD VPSes all have a one-click ability for Node.js which makes life easier.

You should use nginx and not apache.

Ghost requires Node.js 0.10.x (not 0.12.x). They recommend Node.js 0.10.36 & npm 2.5.0. Of course, DreamHost installs node 0.12.x and npm 2.5.x. You can check by typing node -v and npm -v to see what versions you have. Does this mean you can’t run Ghost? No, it’ll work, but it’s not what they like.

You’ll also need an ‘admin’ account on your server. From panel, click on “VPS” and then “Manage Admin Users” to add a new user to that box.

Get Node.js on your VPS

This is quite simple. First, get an Ubuntu VPS. All the new boxes on DreamHost are Ubuntu, so this is the easy part. Once you have the VPS on DreamHost, make a new domain. I made ghost.elftest.net and in the settings, I checked a box to use node.js:

Enabling Node on DreamHost is Easy - click a box

That will force my file path to be ~/ghost.elftest.net/public (normally on DreamHost it’s ~/domain.com you see) but that’s not an issue since this is a new box. That path will be my ‘home’ folder for the domain and where I install everything (if someone asks you ‘where is X installed on your server?’ you tell them that path). That path also means that had I already been using that domain, it would mess up my folders and paths. If you’re doing this on an existing domain, keep that in mind.

Install Ghost

Like I said before, you have to install on your server, not your desktop. Every single doc I read told me I HAD to do this as the server admin, someone with sudo access. I really, really, really did not like that. I mean, epic levels of hate for the idea that I couldn’t have my user account own things, and have the code in my darn web folder.

Me being me, I hatched a plan. I was just going to do it. I was just going to install it in my webfolder and see how it goes. I came up with this theory because when I read How To Install Ghost on DreamHost I noticed it wanted me to have a specific user chown the folders. Not the admin user, but a special ghost user. So what if I just made ‘elftestghost’ the ghost user, and what if I just used ~/ghost.elftest.net/public/ghost/ as my install directory instead of /var/www/ghost/? And this way, I’d be able to pop in and edit things as my normal user.

So here’s what I did.

$ curl  -L https://ghost.org/zip/ghost-latest.zip -o ghost.zip
$ unzip -uo ghost.zip -d ghost
$ cd ghost/
$ npm install --production

That’s it. Ghost is installed. I expected that last step to fail and I’m still a little surprised it didn’t. If it does fail for you, run it as your admin account with sudo, and then chown it over to your ‘owner.’

Configure Ghost

Now that Ghost is installed, you may wonder where it is. We haven’t finished the install yet as it happens. We need to configure it and to do that, we copy the file config.example.js to config.js and open it up.

Once you look at it you see that there are multiple ‘config’ options. Since we called --production in our start command, logically we’re going to edit that section. And lo, there’s the bad URL:

config = {
    // ### Production
    // When running Ghost in the wild, use the production environment
    // Configure your URL and mail settings here
    production: {
        url: 'http://my-ghost-blog.com',
        mail: {},

Change that to the right URL. Mine is http://ghost.elftest.net

Also look for this:

        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: '2368'

Change the host to and save the file. You can also set it to the IP of your server, but as that might change, it’s not required.

Finally you’ll want to set up mail which can be complex. I set up a special account on my own server.

Setup Ghost

Seriously this is not a five minute install. Your site starts with a Hello World type post which tells you all about the glory of Markdown. If you go to your admin page (http://ghost.elftest.net/ghost/) it sends you to http://ghost.elftest.net/ghost/setup/ where you get this:

Ghost: Create User

This actually makes more sense than it did on the Ghost Pro site, where I was wondering why I had to make a user and then a user. Here I’m clearly making a user for the site. There I was making a user for their network (Ghost Pro) and then one for my site.

Setup Nginx Proxy

Will it never end? The reason we want to do this, and this is why we’re on nginx and not apache, is in order to have a pretty URL without the port number.

Log in to your server as your ‘normal’ account (the one who owns the domain, not the admin) and make an nginx folder for config:

cd ~
mkdir -p nginx/ghost.elftest.net

Then make a file called ghost.conf with the following:

location / {
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host      $http_host;
    proxy_pass         http://localhost:2368;

Restart nginx (which yes, you need the sudo power for so yes, you need an admin account) and it’ll magically work. If you get a “502 Bad Gateway” error, it’s because Ghost isn’t running. Speaking of…

Make Ghost Always Start

Okay so I actually do need my admin account. I went with the init script approach to keeping the Ghost always on.

$ sudo curl https://raw.githubusercontent.com/TryGhost/Ghost-Config/master/init.d/ghost \
  -o /etc/init.d/ghost-elftest

Then I edited the ghost-elftest file:


I changed that to where ghost was really installed, but it brings up an interesting thought. What if I wanted multiple ghost instances? Well that’s actually why I named the file ‘ghost-elftest’ instead of ‘ghost’ (which they recommend). With this setup, I can name an init file for each instance and run the commands as sudo ghost-elftest start and so on. Keep in mind, you also have to pick a custom port for each instance.

There are three final commands to run in order to force Ghost to start up on reboot:

$ sudo chmod 755 /etc/init.d/ghost-elftest
$ sudo update-rc.d ghost-elftest defaults
$ sudo update-rc.d ghost-elftest enable

Now I can use Ghost to my heart’s content.


A WordPress killer this is not. It’s just not. If they can make it run without the need for admin/root/sudo access, it has a chance. Once it’s set up, it’s quite nice, but the 5 minute install this is not, and it’s going to need that to beat the beast.

Reader Interactions

%d bloggers like this: