Migrated to Jekyll

Posted on January 14, 2018

Table of Contents


I used it as an all-in-one solution for both blogging and the rest of my website. Eventually I moved the core of my website away from the blog, and WordPress became overkill for just managing the blog. It was too bulky.


I then switched to Ghost. It was wonderfully simple, and articles were edited in Markdown with live preview. The themes were also cleaner than what I was used to with WordPress (although this could have just been because I hadn’t looked at the WordPress themes in a long while). Ghost had everything I needed.

Unfortunately Ghost was a pain to update. There was no automated update process, it had to be done by SSH’ing into my box. On top of this the theme I was using stopped receiving updates, so I needed to patch it as well. This was becoming cumbersome.


In 2018 I decided to get with the times and obtained free Let’s Encrypt certificates for my domains. I then decided to redirect all the HTTP traffic on my domains to HTTPS (a New Year resolution I suppose).

Ghost wanted none of that. I ran into a redirect loop issue for which the only solution was to modify Apache/nginx configuration files. Unfortunately I don’t have access to those files since I run on shared hosting.

I also looked at what it would take to update Ghost from my 0.11.x version to version 1.0.0. Turns out that it’s pretty much impossible to do on shared hosting…

So long, Ghost.


I wanted to avoid having to do any kind of DevOps, such as was necessary with Ghost. Static content was the best solution, and it would allow me to easily redirect to HTTPS.

It would also mean that absolutely all of my hosted content would now be static, so there’s a horde of vulnerabilities I wouldn’t need to worry about anymore. My site’s security would be as good as my host’s security, whereas before I was definitely the weakest link in the “security chain”. I was running an outdated node.js version, and who knows how many vulnerable npm packages. I warmly welcome the newly acquired peace of mind.

I had used a static website generator in the past (DocPad), so Jekyll quickly caught my eye.


I installed Ruby and Jekyll, chose a theme (Clean Blog), then ran an importer tool (jekyll_ghost_importer) for my posts. What I had was already pretty decent, but there were some tasks I needed to do:

  • Configured site settings (title, description, default author, etc)
  • Configured the theme
  • Pagination using a plugin (jekyll-paginate-v2)
  • Added an RSS footer icon
  • Added a Current page / Total pages indicator to the pagination
  • Added a Back to blog link to my 404 page
  • List of categories page and browsing posts per category
  • Many minor tweaks to the theme’s HTML layouts and CSS styles
  • Syntax highlighting support using a plugin (rouge) and setup the Solarized Dark theme for it
  • Optional image resizing and centering site-wide
  • A few .bat scripts for local testing and building for production
  • SEO tags using a plugin (jekyll-seo-tag)
  • Updated permalinks generated by the posts importer to their previous Ghost versions (Jekyll: blog.com/2018/01/14/post/index.html vs Ghost: blog.com/post.html). This also shortens the posts’ URLs.
  • Updated my Apache .htaccess to handle the Ghost-style URLs (redirect blog.com/post and blog.com/post/ to blog.com/post.html for blog posts only)

HTTPS enforcer tool

Although many sites nowadays redirect HTTP traffic to HTTPS, it’s still a gamble when clicking on a link without https://.

My old posts were littered with HTTP links, just because that’s how it was back then. Until recently my own domains didn’t have HTTPS, so all my links to my own pages were HTTP as well.

To clear up the muddy waters I wrote a Python script which finds and replaces all http:// links that can be upgraded to https:// inside the files of a target directory. It checks that the link actually has a correctly functioning HTTPS version before replacing it.

I’ll make a separate post about it soon.