Deploying With Gitea

Blogging like it's 2010, baby!

As of last week this blog gets deployed via a private gitea repository. I know, I know, not that impressive, but I’m going to write it up anyway, and if you don’t care you can smile and nod and close the tab.

I’ve been meaning for some time to set up my own git server for personal projects in lieu of hosting everything on github, and the work I’ve been doing to update this site seemed like a good time to do that. I looked at several options and after a suggestion from a friend I settled on gitea. Gitea is a nice git hosting webapp (and git server) that is really simple to set up. Fundamentally it’s just one go binary to spin up, though you can put nginx in front of (like I did) if that works better for you. Once I had set gitea up I started pushing this site’s repo to it and I realized I had the opportunity to do something clever (that other folks have been doing since static site generators and git were a thing).

I have always updated this site via rsync. This is fine, but it means that deploys of the site may not have been committed. It would be much better to use the git repo itself as the means of deployment.

Gitea has great support for git hooks. So following a few examples I’ve found for using githooks for hugo, I set one up on my server.

I’m using the snapped version of hugo locally, so I installed the snap on the server this runs on. Snaps are isolated from doing things like writing all over the filesystem, so my hook script ended up a bit of a hack, as you can see:



set -e

revert_on_error() {
  "echo 'A problem occurred.  Reverting to backup.'
  rsync -aqz --del $BACKUP_WWW/ $PUBLIC_WWW

trap revert_on_error EXIT

# hugo snap can't write outside of $HOME; use $BUILD_DIR

rm -rf $PUBLIC_WWW/*
rsync -aqz $BUILD_DIR/ $PUBLIC_WWW
trap - EXIT

The trap usage is pure cargo-culting; I need to actually read how it works, but the script does seem to handle failures pretty well (my site has never just been deleted). If I were more daring, I think I could probably also run hugo directly out of the main git repo and skip a step.

But, crucially, it works. If you’ve been looking at setting up something similar and give this a try, I’d love to hear about it. And if you think there’s something wrong here or a way it could work better, I’d also love to hear from you.