This weekend I migrated my blog from Ghost to Hugo. Ghost is great, but I couldn’t justify running a DigitalOcean droplet just for hosting a blog, maintaining it and updating Ghost all the time. Static pages work just fine. So, after looking around at several static site generators I decided to use Hugo.
Here is what I did to migrate:
- Created a new hugo site on my local system.
- Got a JSON backup of my Ghost content using the export tool.
- Got a tar.gz backup of my
/var/www/ghost/static/folder, with all static images etc.
- Moved the static content into
- I used this script to convert the json backup file to individual markdown pages. I had to adjust the dateformat so that it fits with what I was using in Ghost.
- Pushed it to git on GitLab (private repository)
- I tried to find a way to recreate the look & feel of my Ghost blog in Hugo. I ended up using a theme that looks like Ghost’s Casper theme: https://github.com/dencold/hasper. This theme is itself a fork of the (original adaptation)[https://github.com/vjeantet/hugo-theme-casper] but the templates are cleaner. I edited it a bit more; my fork of the hasper fork is here.
- I set up hugo to use my custom theme as a git submodule, using
git submodule add https://gitlab.com/ikoz/ikoz-hugo-theme-hasper.git themes/ikoz-hugo-theme-hasper. This way I can keep my hugo static content private while the theme is public. If I update the theme, I just need to push it to it’s own repo and within ghost do a
git submodule update --remote.
Gitlab also offers Gitlab Pages, which, much like Github Pages allows you to automatically publish your site. I adapted my Gitlab CI yml file to build the site using the latest hugo release (v.017) and support submodules so that the theme works fine. Here is the config:
image: alpine:3.4 before_script: - apk update && apk add --no-cache bash git openssl - git submodule init - git submodule update - wget https://github.com/spf13/hugo/releases/download/v0.17/hugo_0.17_Linux-64bit.tar.gz - echo "6a74626b64434a5ee9fc5ec4fbf22ce6 hugo_0.17_Linux-64bit.tar.gz" | md5sum -c - tar xf hugo_0.17_Linux-64bit.tar.gz && cp ./hugo_0.17_linux_amd64/hugo_0.17_linux_amd64 /usr/bin/hugo - hugo version test: script: - hugo except: - master pages: script: - hugo artifacts: paths: - public only: - master
I adjusted my Cloudflare DNS setup so that it points to my Gitlab Pages hostname instead of the DigitalOcean droplet. I also set up strict SSL, origin certs, HSTS and whatnot.
Finally, for each blog post I also adjusted the “slug” as needed and set up aliases so that all internal and external links to my posts still work. Disqus comments also got migrated automatically for each post, which was nice.
Everything seems to work properly. Now, for every blog post I publish I just need to write the markdown file locally and do a commit and
git push; everything else gets done automatically and the site is updated in seconds.