This blog uses Hugo as a static website generator and gitlab pages as a hosting service. In this short post, I want to share how to set this up, as well as how to add your custom domain if you have one.

Pre-requisites

Hugo setup

All steps here are taken from Hugo quickstart.

First, we need to install the Hugo binary. There are different ways to do this documented here. Pick the method that works best for you.

To check that Hugo is installed, run hugo version in a terminal.

Next, let’s initialise our website with hugo new site acoolname. This will create a directory acoolname with folders/files for our website.

Now we can add a theme:

cd acoolname
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke

Hugo uses a main config.toml file to keep the website’s configuration. Amongst other things, you can specify the theme:

# config.toml
theme = "ananke"

Now we can start writing some content for our blog. Content lives under the content/ directory. You can manually create directories or files under it, but Hugo provides a command that helps out with a few things like setting the date and draft status:

hugo new posts/my-first-post.md

This will create a new directory content/posts/ with a markdown file. Write some content to that file2 and save it when you are done.

Now we are ready to serve the files locally with hugo server -D3.

Gitlab setup

In Gitlab, create a new project with the name <username>.gitlab.io. If you do not give it this name, project will live under a path <username>.gitlab.io/<projectname>. This makes it difficult to point your DNS records to the correct place.

Next, we need to point our local copy of the website to this newly created repository. If you haven’t already, add an initial commit and push to your newly created repository.

Now that we have some content, let’s try to publish it! Gitlab has very nice CI/CD integration that we will leverage for this. Create a .gitlab-ci.yml file at the root of your repository. This file defines the CI/CD stages and what commands to run. We want to build our Hugo website whenever we push to the main4 branch so this is what it will look like:

image: registry.gitlab.com/pages/hugo:0.82.0

variables:
  GIT_SUBMODULE_STRATEGY: recursive

pages:
  script:
  - hugo
  artifacts:
    paths:
    - public
  only:
  - main

We use the stage name pages and tell it to run hugo to build the website. The artifacts block tells Gitlab to publish the generated files so that they can be served by Gitlab pages. The only block specifies that we only want to run this on the branch main.

Now, whenever we push any changes to the main branch, Gitlab will build our website for us! You can take a look at the output by navigating to: <username>.gitlab.io.

Adding your own domain

If you want to access your website through a custom url instead of <username>.gitlab.io, you will need to do some extra setup in Gitlab pages. This is explained in detail in the documentation.

From your repository’s page in Gitlab, go to Settings > Pages. In here, you can click the New Domain button towards the top right of the page.

You need to verify your domain by adding the TXT record shown in the Gitlab UI to your domain registrar. Additionally, you need the following A record to point your domain to the Pages server:

example.com  A	35.185.44.232

Now, all you have to do is wait for the DNS records to propagate and you should be able to access your website through example.com!


  1. I used Namecheap to register my domain name as well as manage my DNS. Feel free to use any services that you wish. ↩︎

  2. You can use the markdown guide here if you need a syntax refresher. ↩︎

  3. The -D here indicates that we also want to include draft files. This is very helpful for development as we only want non draft articles to be published to the production website, but still want to be able to see our drafts when editing. Now you can navigate to http://localhost:1313/ to see your website in action! ↩︎

  4. In light of recent debates, git now suggests renaming the master branch. I will try and use main as the default for my projects going forwards. ↩︎