Hugo static website build by GitLab pipeline running in Docker
Every now and then I stumble across interesting new ways for developing websites. After using static HTML sites, TYPO3-, WordPress-, Drupal- and Vue.js-based variants, it was about time to switch again.
My previous site was based on Vue.js.
It was built out of thousands of npm packages resulting in a relatively large
app.js file running in the browser.
Just for the sake of having a backend providing the content, I wrote a web API in Rust with the help of Rocket.
It was quite fun developing it, but of course kind of an overkill for mostly static content.
This time, I’m using Hugo to build my website. Hugo is a static site generator developed in Go. It compiles the website’s content written in Markdown and the selected theme into static HTML files and the corresponding folder structure.
How is it working
I followed Hugo’s quick start guide, included the hello-friend-ng theme and configured the basics.
Using the command
hugo new posts/blog-title.md, a new blog post is generated.
This file contains some meta information, for example date, title and tags.
The actual blog post is written in markdown.
Same goes for classic pages, e.g. About, except that fewer metadata is required.
So after the skeleton was prepared, I manually converted my WordPress blog posts into markdown files.
To run a development server, Hugo’s CLI ships a webserver that will serve the compiled static website.
In addition, changes are recognized and the site gets reloaded.
This webserver is started via
hugo server -D, where
-D tells Hugo to include content marked as draft.
Of course, Hugo provides a detailed documentation about how to create templates, how the CLI is working and so on.
My source code is stored on a private GitLab instance.
By default, Hugo’s folder for the compiled website is
public that I
The next step was to integrate the static website into my existing setup, which is based on Docker, Docker-Compose and Traefik.
This meant, that I had to find a way to provide the compiled static website via Docker.
I decided to automatically build a Docker image for each change. This Docker image should contain the compiled static website served by nginx.
For this, I wrote a
Dockerfile consisting of two stages:
- Compile to static website
- Create a Docker image with nginx serving the website
Now that it was possible to build a Docker image serving my compiled website, I needed to find a way to run it.
The next step is to store and deploy the image.
Since I activated GitLab’s internal container registry, this is for me the place to go.
GitLab defines pipelines in
.gitlab-ci.yml files, which is a pretty decent feature regarding reproducable builds.
So it was time to write a
.gitlab-ci.yml file capable of
- Building a Docker image based on the above
- Pushing the image to GitLab’s internal container registry.
For my GitLab instance, I have a GitLab Runner registered that is using Docker to build. Yes, this means I’m building a Docker image inside a running Docker container which is called Docker-in-Docker (dind).
This pipeline is running for every commit on every branch. But only new versions based on the master branch are pushed to GitLab’s container registry.
As described in a previous post, all of my websites are running in Docker containers.
Traefik is receiving and forwarding all requests to the appropriate containers.
So I wrote a
docker-compose.yml file integrating my Hugo-based website into this setup.
Currently, I have to manually update the deployment, as soon as a new Docker image of my website is available:
docker-compose pull docker-compose up -d --remove-orphans
This might be something to look at later on, but currently I’m happy with my setup.
Creating the first static website with Hugo is very easy. And with the help of one of the hundreds of beautiful themes, it is not much work to even get a beautiful website.
Combining Hugo with CI/CD pipelines is a way that I personally like way better than WordPress-based websites. Of course, Hugo is not suitable for every need, but for my small private website and blog, I see it as the best solution at the moment. The big advantages for me are the easy way of writing content and its increased security by just shipping plain HTML files.
Even if there is no administration page like in WordPress or Drupal, I can still edit my content in GitLab. The only thing currently missing is the automated deployment to ship the changes to the live site.