Goodbye WordPress, Hello Ghost

This post is 4 years old. (Or older!) Code samples may not work, screenshots may be missing and links could be broken. Although some of the content may be relevant please take it with a pinch of salt.

I made a decision to stop using WordPress - I have been using that 'blogging' engine for quite a while (even my first blog was using WordPress and that was back in 2006), but the time has arrived for a change. Most people would argue that actually WordPress is not longer a blogging engine but something entirely more - a CMS, most likely. This idea has lead John O'Nolan to come up with an idea of an engine that is 100% for blogging. And Ghost was born.

Ghost is really just a blogging platform and what's absolutely great about is the fact that it's using node.js and its source code is completely available on GitHub.

I am running the blog on a Ubuntu (12.04) Amazon EC2 instance, with nginx responsible for the reverse proxy. I realised that there are not many instructions on how to do this so here's what I have done:

First upgrade nginx to 1.4.3 (latest package at the time of writing). Run the command below to determine your version:

$ nginx -v
nginx version: nginx/1.4.3

Note that a standard sudo apt-get update may not be enough on the EC2 instance to upgrade nginx. Here's what I've done:

  1. Add the nginx repo deb [http://nginx.org/packages/ubuntu/](http://nginx.org/packages/ubuntu/) precise nginx to /etc/apt/sources.list
  2. Add a public key sudo apt-key adv --keyserver [keyserver.ubuntu.com](http://keyserver.ubuntu.com) --recv-keys ABF5BD827BD9BF62
  3. Remove existing nginx: sudo apt-get remove nginx-full && sudo apt-get remove nginx-common (this does not remove your server configuration files)
  4. sudo apt-get install nginx will now install from the official repo

Once this is done, follow the Ghost installation walkthrough to install node.js, npm and Ghost itself. Once that's done and you've configured Ghost and setup the config.js file correctly, it's time to fire up the reverse proxy - in order to do that, follow these steps:

  1. SSH into your server and remove the default nginx configuration file under /etc/nginx/sites-available/default
  2. Create a file under the same path, and name it after your site, so for example: /etc/nginx/sites-available/mysite. The content should be:
server {
    listen 80;
    server_name YOUR-DOMAIN;
    access_log /var/log/nginx/YOUR-DOMAIN.log;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HOST $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://127.0.0.1:2368;
        proxy_redirect off;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_max_temp_file_size 0;

        client_max_body_size       10m;
        client_body_buffer_size    128k;

        proxy_connect_timeout 90;
        proxy_send_timeout 90;
        proxy_read_timeout 90;

        proxy_buffer_size 4k;
        proxy_buffers 4 32k;
        proxy_busy_buffers_size 64k;
        proxy_temp_file_write_size 64k;
    }
}

Please change YOUR-DOMAIN to, well - you know, to your domain address. (note, you need to change this at two places above)

It's time to add a symbolic link from sites-available to sites-enabled. In order to achieve this, run: sudo ln -s ../sites-available/YOUR_DOMAIN YOUR-DOMAIN while you're in the sites-enabled folder.

At this time, you can restart nginx.

If you've done everything right, you can now navigate to your domain and see Ghost's welcome page.

Additional notes: If you're also changing your domain, you may want to add some 301 redirects from your old domain to the new one and also make sure that the WordPress links redirect to the new Ghost links properly. In my case (as my WordPress was setup using the 'domain/year/month/day/article-title' format), I am using the following redirect in my .htaccess:

RewriteCond %{HTTP_HOST} !old-domain$ [NC]
RewriteRule ^([0-9]+)/([0-9]+)/([0-9]+)/(.*)$ http://new-domain/$4 [L,R=301]

Another warning - I tried to be clever and once I have imported the JSON dump from my WordPress blog into Ghost, I realised that now I need to update all the internal links from the WP structure to the new Ghost structure. I quickly opened the file and did an edit-replace, saved the file and re-imported it. This is when everything has gone wrong. Ghost basically duplicated all the posts that I had and it took me some work to get things right (I actually had to connect to the sqlite database) - so be wary of this.

Otherwise, good luck with the transition!