Why?
I’ve been blogging for quite a few years now, starting on Blogger, soon onto WordPress, and then to Ghost a couple of years ago. Blogger was fairly lame, WP yucky, but I really do like Ghost. It’s simple and powerful and was perfect for my needs. My needs being, an outlet for technical content that respected formatting, worked with a markup language (Markdown), and didn’t f**k things up in the way that WP often would in its WYSIWYG handling of content.
I ran Ghost self-hosted on AWS EC2, and this was the start of this particular story. Whilst 20 years ago, even 10 years ago, I’d quite happily spend an evening immersed in a hack project to get something working, times are different now. With a wife and two kids—and a fair bit of travel for work—the time I have at home I don’t want to be spending on getting shit to work. And therein lies the beauty of PaaS. Never mind cloud-bollocks or what the acronyms stand for—in essence you write your blog, and someone else worries about all the rest of it. SSL certificate expired? Not my problem. Ghost needs upgrading? Not my problem. Whereas if you self-host…totally your problem.
In addition, paying for my AWS costs out of my pocket started to grate just a little. A few bucks here and there kinda add up over the course of a couple of years. Nothing major, but enough to make me pause and look around. The final itch I had was Markdown. Now I do like Markdown, but a little less than I used to—and that’s because I found Asciidoc. Asciidoc finishes what Markdown starts. All the slightly limited functionality in Markdown once you get beyond bold
and italic
, asciidoc swoops in and gives you in spades. And as much as I liked Ghost, it doesn’t support Asciidoc.
Enter Hugo
Hugo is one of the breed of blog platforms that works by generating static HTML, which makes it simple (fewer moving parts, no database backend, etc) and nice and fast. Because it just generates HTML you can host the contents on Github Pages (bye bye AWS hosting costs), and because it is just static HTML one can worry less about falling behind in versions. After all, Github are doing the actual hosting and can worry about securing the server; my only bit is the static HTML, and who cares if it’s generated by an older version of code?
Getting set up
To get it set up locally on your Mac:
brew install hugo
There’s a ton of quickstart tutorials out there—I picked the first off Google and went with that :)
I’ve got my blog source on a github repo, and then the output from Hugo on another - my github pages repo. Using a script I got from somewhere (apologies I didn’t keep the source link) I can automagically build and deploy the changes made locally up to both repos, and thus publish new content.
So far I’m doing everything in text editor (VS Code). All I’ve missed so far compared to Ghost is that blog tags, slugs etc are entered manually in the header of the post itself, which seems a bit tedious and error prone:
+++
categories = ["oracle", "cdc", "debezium", "goldengate", "xstream", "logminer", "flashback", "licence", "ksql"]
date = 2018-12-12T09:49:04Z
description = ""
draft = false
image = "/images/2018/12/IMG_7464.jpg"
slug = "streaming-data-from-oracle-into-kafka-december-2018"
tag = ["oracle", "cdc", "debezium", "goldengate", "xstream", "logminer", "flashback", "licence", "ksql"]
title = "Streaming data from Oracle into Kafka (December 2018)"
+++
Check out the nice syntax highlighting there - using the highlight
shortcode. You can use standard code markup from asciidoc but so far I’ve not found out how to get it to do the syntax highlighting on it too:
echo 'This is a bash statement in asciidoc code markup'
echo 'This is a bash statement in Hugo syntax highlighting markup'
Migrating from Ghost
This was pretty easy:
-
Export from Ghost to get a json file
-
Convert it with https://github.com/jbarone/ghostToHugo
./ghostToHugo -p ~/git/rmoff-blog/ --dateformat "2006-01-02 15:04:05" ~/Downloads/rmoffs-random-ramblings.ghost.2018-12-15.json
-
Download the
content
folder from Ghost and move the images folder tostatic
in your Hugo deployment. For me this was sufficient for all the paths to match up and all existing posts to retain their images -
Ghost uses
tag
for its tag URLs (e.g.link:/tag/goldengate/
), whereas Hugo usestags
. You can change your config to match this (tag: tags
→tag: tag
):taxonomies: category: categories tag: tag
You then need to change each article’s header to use
tag
instead oftags
- a quicksed
will do this (another reason why markup is so powerful; you don’t lose metadata and you can bulk-process files easily)sed -i '.bak' 's/^tags =/tag =/g'
Themes
There’s a ton of themes available; I’m using the rather nice Story theme from Baron Schwarz. Installing themes is a simple matter of adding it as a submodule into your existing Hugo folder
git submodule add https://github.com/xaprb/story.git themes/story
and then setting the theme name in your config.yaml
file.
Different themes have different properties; this one reserves H1 and H2 for its own use, so you need to make sure your articles use H3 onwards. Again, easily fixed with sed
(all mine started at H2):
sed -i '.bak' 's/^##/###/g'
If I get round to it I might try and customise it myself to make the body just a bit wider; a lot of my articles include code samples and it’d be useful to see a bit more of them.
You can configure the top menu items using the menu
configuration in config.yaml
(mine is public here)
Wanna See Under the Covers?
If you want to see how this is all set up, the code is public.
GitHub Pages
Setting this up is as simple as pushing code to a github repo. It even provides SSL certs, that you don’t have to manually renew 👌
Comments
I used Disqus for comments on my Ghost blog, but got very few really, and those I did half were asking for help and would be better posted on StackOverflow or elsewhere. I wrote an article recently in which I invited comments and discussion in the comments facility; I got zero there, and a good half dozen on Twitter, LinkedIn, and email.
My conclusion is that comments are not really that useful nowadays; the social networks have pretty much replaced them—and so I’ve not bothered to migrate them over here. I think that they do actually work out of the box with Hugo and Disqus, but the theme I’m using doesn’t support them and that doesn’t bother me. It just makes for a cleaner site.