Moving from Jekyll to Ghost

It's that time again: After moving from TYPO3 to Wordpress to Jekyll over the years I'm now moving my website to Ghost and consolidate and into one single website / blog.

Not that I don't like Jekyll anymore, it was just getting "to complicated" to write blogposts. Here comes Ghost: It has a very great editor based on Markdown and a simple admin interface, exactly what I was looking for.

I've chosen to use the default Ghost template called Casper and keep away from customizing it outside of the default possibilities. This helps me to keep the software up-to-date and not having to invest a lot of time to upgrade to newer versions.

The migration

Converting all the posts from Jekyll to a Ghost format can be done using nodejs-jekyll-to-ghost. This produces a file which can be imported into Ghost. Images need to be imported manually after the text is there. It took me sometime to go over each post, upload images, fix text alignements and remove Jekyll specific code. After all it was worth the effort!

URL redirects

Links to my Jekyll blog should still work, so I wrote a redirects.json and uploaded it to Ghost. More information about this feature of Ghost can be found in the documentation.

Hosting Ghost

As I run my own OpenShift single server instance I've chosen to host Ghost on OpenShift. This is fortunately very simple as the official Ghost Docker image just runs on OpenShift. A PV needs to be mounted to /var/lib/ghost/content so the persistent data gets preserved when redeploying or updating Ghost.

Comments with ISSO

I stick with ISSO for comments as Ghost has no integrated commenting system and Disqus is not an option for me. As the URLs have changed and two ISSO instances have been merged together, I had to fiddle around with the SQLite3 database. Thanks a lot DB Browser for SQLite. Some hints:

  • Connections between Blog Post and Comments are stored in the table threads so I had to update this table. Updating to the new URL structure was therefore just a matter of updating the paths in the threads table
  • Comments are stored in comments and connections to the Blogposts are made via thread id (tid). So I "only" had to merge the two ISSO DBs and update the IDs.

Integration of ISSO into Casper can be found in my fork of Casper: (branch tobru_master).


The Piwik tracking code is simply inserted in "Code injection" in the "Blog Header" part. All tracking happens on my own server under and respects the DoNotTrack header.

You've successfully subscribed to Tobias Brunner aka tobru
Great! Next, complete checkout to get full access to all premium content.
Error! Could not sign up. invalid link.
Welcome back! You've successfully signed in.
Error! Could not sign in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.