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:
- https://rmoff.net/2018/12/17/moving-from-ghost-to-hugo/
- https://dwmkerr.com/migrating-from-ghost-to-hugo/
- ghostToHugo
The migration process
Backup the site
- 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
- 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
- Copy all of the images across:
$ scp -rp [email protected]:/var/www/ghost/content .
- 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.
- Convert
- Remove duplicate images resulting from page bundle migration.
- Generate
redirects.json
file for original Ghost blog.
- Copy pages and images to pages bundles and process markdown:
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.