Migrating from WordPress to Ghost

I just finished migrating this blog from WordPress to Ghost.


WordPress served me well for a long time, but it led to a setup that was hard to maintain. In order to get fairly basic functionality, I used a complex custom theme and a handful of plugins that all needed to be kept up to date.

It was also becoming increasingly annoying to write posts in the WordPress editor, especially as nearly every other tool I used supported Markdown.

It finally came to a head when the theme was removed and I had to do something: Suffusion Not Available Any More. At that point, it seemed to be about as much work to find and configure a new theme (and upgrade all of my plugins) as it would be to find a new blogging tool.

I looked around and Ghost seemed good. I knew others who were very happy with it, and there was a clear migration path from WordPress. It also seemed full featured and fast enough that I wouldn’t have to install a lot of plugins (like I did with WordPress).

How I migrated

The migration wasn’t too painful, but it was involved. Hopefully, I can help others out in the future by documenting my steps.

Running Ghost

The first thing I needed was a way to run Ghost. I didn’t want to worry about installing all of Ghost’s dependencies, so I decided to run it via Docker. This way, I can also upgrade by just changing the version of the Docker image. I set up an init script that basically just does this:

  /usr/bin/docker run \
    -e NODE_ENV=production \
    -p \
    -v /var/www/ghost:/var/lib/ghost \
    --log-driver=syslog \
    --rm \

This runs ghost on and mounts /var/www/ghost into the container. This way, I can keep my files across Docker containers. Then, I fronted this with Apache.

Configuring Ghost

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/styles/github.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/highlight.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/languages/clojure.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/languages/groovy.min.js"></script>
  pre {
    word-wrap: normal;
    -moz-hyphens: none;
    -ms-hyphens: none;
    -webkit-hyphens: none;
    hyphens: none;
    font-size: 0.7em;
    line-height: 1.3em;
    pre code, pre tt {
    white-space: pre;
    $("section.post-content").after('<div id="disqus_thread"></div>');

Migrating posts

I installed the Ghost plugin in WordPress and exported my data as a JSON file. The conversion from html to markdown didn’t go very well (especially for code blocks). I dug into the plugin, and even opened an issue on GitHub (https://github.com/TryGhost/wp-ghost-exporter/issues/7), but the project seems dead.

Rather than fix all of the markdown by hand, I found another converter that did a better job: Pandoc. I wrote a small script to use the existing export, but replace the markdown with a better conversion:

# reformat_markdown.rb

require "json"
require "open3"

def main
  parsed = JSON.parse(File.read(ARGV.first))

  parsed["data"]["posts"].each do |post|
    post["markdown"] = fix_markdown(html2markdown(post["html"]))

  puts parsed.to_json

def html2markdown(html)
  Open3.popen3("pandoc -f html -t markdown") do |stdin, stdout, stderr, wait_thr|

    return stdout.read

def fix_markdown(markdown)
  markdown.gsub(/ \{lang="(.*?)"\}/m, '\1')

main if __FILE__ == $0

Then, I loaded this JSON file into Ghost. Most posts looked ok, but I did have to fix the formatting on a few. I didn’t look through every post, however, so it’s likely that some of the older posts have incorrect formatting.

Migrating comments

I decided to switch my comments to Disqus for ease. I followed the Manual Import instructions, exported my data from WordPress, and imported into Disqus.


So far, I’ve been very happy with Ghost. The writing experience is really nice (side by side markdown editor and preview). And I’ve already done an upgrade simply by bumping the version number of the docker image.

I do wish I could customize my author page a bit more with links to twitter, github, etc. And I would like to add a sidebar with extra info about me and highlighted posts. I may consider switching to a theme which gives me some of this.