My Hugo Workflow

One of the advantages of WordPress is that you can edit your website wherever you have an internet connection. With Hugo (or any static site generator, for that matter) you can’t do that so easily, although offline editing is much easier. Here, I’m going to tell you how I’ve got Hugo working in harmony across all my devices, as well as how I would like to have done it.

Static site generators like Hugo allow you to edit files on your hard drive and have them turned into HTML files for deployment on a dumb server. But the problems quickly become apparent when you think through the implications of a distributed setup. What if you have several devices you want to edit your content on? How do you sync versions across them? Do you have to install and run Hugo on every computer you own? What about mobile devices?

The problem is that, yes, you have a single copy of your HTML on a central server, but that doesn’t get you very far. If you edit that HTML (which is not the idea behind a static site generator), the next time you build your site using Hugo, those changes have disappeared.

Indeed, if you have several devices all with their own copy of your website, then build it properly with Hugo, and deploy just the HTML, they will overwrite each other too.

The Git Setup

I’m going to tell you what setup I arrived at, before going on to tell you the setup I would have liked but failed to implement.

Whatever setup I have, it needs to be:

  • a central repository for content so I can edit my articles from anywhere,
  • compatible with iOS devices, such as my iPad, and
  • capable of synching versions between devices.

My central repository is – no surprises there – Git. I don’t have a Github account, and didn’t want my draft articles out in public, which means I can’t use the free version. So I need something capable of running a Git server.

Given that I don’t want to run Hugo on every computer I edit from (and can’t, on iOS devices), having a virtual server isn’t a bad idea anyway because it enables me to build the site by running Hugo on the server rather than on the client device then synching just the HTML.

So for my Macs (iMac and MBP), I can just use Git and don’t even need to have Hugo installed. For my iOS devices, I’m using Working Copy as a Git client (the paid version, as the free version doesn’t allow you to push changes).

Automatic Checkout and Hugo Build

I’ve got a bare repository on my server, which gets checked out to the webroot whenever a change is detected. This works with a Git hook, as described here.

I made one simple addition: after every deployment, Hugo is called once to build the website. (I originally used a Systemd process to have Hugo running all the time, but presumably it’s more resource-efficient just to hook into Git in this way). The command you need to add to the end of the file is: /path/to/hugo/binary/hugo -s /path/to/hugo/project

This executes Hugo once on the project after it has been checked out.

What’s In and What’s .ignored

The only issue in deciding what should be tracked in the repo and what not was which media files to include. Looking around on the internet, it seems you don’t actually go to hell for including some media in Git. However, because Git has at least two copies of everything (your working directory and the repo), as well as the fact it keeps every version, it’s not a bad idea to limit the number of large files. The least you can do is ignore Hugo-generated files, so I did that. It required adding the following to the .gitignore file on the root level of the project: resources/_gen

Working on iOS Devices

Working Copy on iOS seems to work well (touch wood). You can use external editors (I’m using iA Writer for this article) because it integrates nicely into the file system. The upside is that it tracks all your changes; the downside, that you can’t just edit and save but have to commit and push everything for it to be changed on the website.

Three Downsides

There are only three downsides to this approach that I can think of:

  1. As mentioned above, you can’t just edit files but have to commit and push them using Git
  2. Reviewing drafts isn’t possible because they don’t get built until they’re published (unless you have a copy of Hugo on the machine you’re editing on)
  3. You can’t use Hugo to generate posts and other content types from archetypes with pre-filled information such as the date. However, I’ve simply added a draft template to my content/posts directory, so I can duplicate that and edit accordingly.

A Nice Setup but I Would Like to Have Done it Differently

Now, I can pull the repo onto any device I want to use it on and edit to my heart’s content. However, I would actually have liked to do things much differently but, as things stand today, it wasn’t possible. I spent so much time trying that I’m going to bore you with it nevertheless.

Using Raspberry Pi to Compile my Website

Yes, the idea involved a Raspberry Pi. Ideally, I would have liked to have the following setup:

  • A Google Drive/Dropbox folder for the content
  • A Raspberry Pi syncing the content folder and watching for changes
  • The Pi compiling everything with Hugo whenever a change occurs, and copying just the HTML to a cheapo hosting server

The benefit of this setup would have been that I could use a cheap host that needed only to serve HTML and support SSH or FTPS as well as Mod Rewrite for pretty links. It would also have been quite secure because I wouldn’t have to open a port in my home network in order for the Pi to be updated with any changes. It would also have been easy to update and add content. Alas, it wasn’t to be.

A kind of prototype worked on my server. For that, I used the Linux version of Dropbox which is relatively easy to configure. Unfortunately, as I found out later, the free version is limited to three devices including the server itself.

You can’t change the location of the Dropbox directory: it’s in the home folder of the user you run it under. That’s not a problem though, because you can use simlinks to link the /content folder within your Hugo install to the one within your Dropbox folder and it works fine.

Hugo worked on my Ubuntu server. I set it up as a Systemd service, so it was started whenever the system was rebooted. I had to get the extended version though, because I used Hugo to process SCSS. (This was an important detail that made the RPi setup impossible.)

It worked a treat, and I thought it would be a breeze to transfer this setup to the Pi.

Not a Piece of Pi

The hurdles at the moment for the Pi setup are:

  • Installing the extended version of Hugo on Pi is either impossible or very difficult because there isn’t a binary available. I needed this because I use SCSS. I ended up going down a rabbit hole that involved trying to install Golang so I could compile it myself, but gave up after a while
  • Dropbox doesn’t work on the Pi
  • As an alternative, I tried RClone with Microsoft One Drive (as I have a subscription, so could have used unlimited devices). This doesn’t sync in both directions, and I couldn’t get it working on the Pi reliably

So no Hugo, no Dropbox: my project lay in pieces on the floor. Oh well, for the sake of €10 per month and €21 to buy Working Copy, it wasn’t worth pursuing. Maybe I’ll come back to it at another time and find that all the projects I need have been made Raspberry compatible. Until then, at least my content will be nicely revision controlled in Git.