Automatically deploy a static blog built with Hugo using Gitea and Webhooks

Posted on | 458 words | ~3mins

Motivation

Setting up automatic deployment makes life much easier, it means that you just have to push the raw markdown to the server using git, and on the server the static HTML files are then generated automatically, without any need to trigger this step manually.

Some people use hilarously complex setups for this including regular CI/CD tools like Jenkins which aren’t really needed for such a simple task. This is why I describe my minimal setup with Gitea and webhooks. Instead of Gitea, you could also use Forgejo.

Prerequisite

First, you need a repository for your blog in your Gitea server. Clone this repository to your local computer where you will write the articles and into your web root directory.

Setup webhook

On your server install webhook. This will provide a minimal webserver which can be used by Gitea to trigger a new site build when pushing new content to the repository.

Configure webhook to provide a webhook endpoint for your blog:

[
        {
                "id": "generate-my-blog",
                "execute-command": "/var/www/scripts/generate-hugo-blog.sh",
                "command-working-directory": "/var/www/path-to-your-blog-http-root"
        }
]

With this config, webhook will run a webserver running on port 9000, and when calling the /hooks/generate-my-blog URL, it will call the script generate-hugo-blog.sh. Please note, that by default webhook will listen on all interfaces, so it might be a good idea to pass this parameter to the webhook daemon (e.g. in your systemd service) so it listens only on the localhost interface: -ip "[::1]"

Setup Gitea

In the configuration page of your blog repository, go to the Webhooks page and add a new webhook which calls your webhook URL http://[::1]:9000/hooks/generate-my-blog. Gitea should use HTTP method POST for it and it is only needed to run on push events.

Bash Script for static blog generation

The bash script is needed for pulling the current changes from your repo into your web root and calling hugo to generate the static files.

For pulling the latest changes, create a new ssh key pair using ssh-keygen. Now add this SSH key as a Deploy key to your Gitea repository.

For the bash script, it is important that git also uses said ssh key pair for pulling the repository.

#!/bin/sh

cd /var/www/path-to-your-blog-http-root
git -c core.sshCommand="ssh -o 'UserKnownHostsFile=/dev/null' -o 'StrictHostKeyChecking no' -i /var/www/scripts/ssh_key_http" pull
HUGO_ENV="production" hugo

Finishing Up

As a last step, make sure to test the setup and update your webserver so that it uses the /public folder as the new public webroot. Also make sure the permissions are such that the bash script can write to the cloned directory and that the .git repository is not exposed to the public.

Now, everytime you push changes to the configured branch, they will be pulled automatically and built into static files which will be served by your web server. Happy blogging!