Migrating duk.io from Ghost to Hugo

last updated: Apr 15, 2024

I decided to migrate this blog from Ghost to Hugo. If you’re reading this, then the migration was a success.

Why migrate from Ghost to Hugo?

  • Ghost v5.0 was released in May 2022 and this blog was still running on v1.22. Aside from the potential security implications, it really was time to upgrade if I wanted to maintain any semblance of support.
  • I loved the simplicity of Ghost v1, but Ghost now includes memberships, subscriptions, podcasts, NFTs, newsletters, special offers, audience segmentation, analytics, etc. It seems like a great platform for professional publishing, but it’s well beyond what is required here.
  • I was in the process of building a few new websites, and had settled on Hugo as the generator. Dealing with a single system across all of my sites reduces the mental burden of staying up to date with their changes.
  • Aside from comments (which are being dropped for now), this blog has no dynamic content, so there is no need to serve it dynamically.
  • I prefer file based content backed up in Git to a database solution.
  • I already use Github and BitBucket for my code, so it makes sense to store content there too.

Why Hugo instead of Gatsby, Jekyll, or another SSG?

I know very little about Gatsby, Jekyll and other SSGs, but I do know that I generally prefer an app in a single, statically linked, batteries included binary rather than a framework built on A, which is built on B, with a tree of dependencies. From that angle, Hugo seemed more suitable for me, and despite a great deal of negative commentary around the documentation, I found it reasonably easy to setup and configure.

It also helped that many had come before me and the available migration tools were more than adequate:

The migration process

Backup the site

  1. The Ghost (v1.22) admin panel includes and export function under the Labs menu, which exports all posts to a single JSON file. This does not include the images, which are manually copied later.

Migrate to Hugo

  1. Run the very useful ghostToHugo tool (v0.5.3), which produces a basic Hugo site with all of the posts written as individual markdown files in the content folder.
$ ./ghostToHugo --dateformat "2001-01-01T00:00:00.000Z" --force --hugo www.duk.io duk-io.ghost.2022-09-23.json
  1. Copy all of the images across:
$ scp -rp [email protected]:/var/www/ghost/content .
  1. Create and run a bunch of Node scripts to:
    • Copy pages and images to pages bundles and process markdown:
      • Convert figure to shortcode.
      • Fix missing space in markdown headings (i.e. #Heading -> # Heading).
      • Change heading levels to new 2/3 structure.
      • Remove unused classes from prior grids/lightbox.
    • Remove duplicate images resulting from page bundle migration.
    • Generate redirects.json file for original Ghost blog.

Hosting a static site is simpler and cheaper.

An additional benefit of the migration is that I no longer require any compute to host the site. It was previously hosted on a small Digital Ocean VM, which although relatively cheap, came with maintainence requirements and increased security risks.

It is now hosted on Cloudflare Pages, with the only dynamic element being a single Cloudflare Worker to handle contact form submissions.

Prev in section:
How to configure an ATMega328p to…