Create website with Hugo using GitLab Page and Namecheap Domain Registrar

Planning

  • Custom domain: www.andrewmercer.net
  • GitLab Page: andrewmercer.gitlab.io
  • GitLab project name: andrewmercer.gitlab.io

NOTE: My method was to match hugo site name with GitLab project name, create the GitLab project, do not clone it, create Hugo site with same name and follow the GitLab directions for an existing directory.

Create GitLab Project

  • https://docs.gitlab.com/ee/user/project/pages/getting_started_part_one.html

In my case, I am creating a GitLab user page, so I followed the requirements for user pages.

See section:

Under your username, john, you created a project called john.gitlab.io. Your project URL is https://gitlab.com/john/john.gitlab.io. Once you enable GitLab Pages for your project, your website is published under https://john.gitlab.io.

To summarize, for my page to be located at url https://andrewmercer.gitlab.io, I create a project called andrewmercer.gitlab.io, the project url of which is https://gitlab.com/andrewmercer/andrewmercer.gitlab.io.

Steps to create the GitLab project

  • I selected a blank project and will be creating the necessary site data using the hugo cli binary.
  • Project name: andrewmercer.gitlab.io
  • Project deployment target: GitLab pages
  • Visibility: Public
  • Uncheck initialize README
  • Uncheck SAST (will add later)

Install Hugo and Golang

Install Golang

  • https://go.dev/doc/install

Feel free to use my Ansible role to install Golang (support for Linux only)

Install Hugo

  • https://gohugo.io/installation

Feel free to use my Ansible role to install Hugo (support for Linux only)

Follow the quickstart guide to create a new site

  • https://gohugo.io/getting-started/quick-start/#create-a-site

Create the new site, initialize git repo, add remote and default them submodule

hugo new site andrewmercer.gitlab.io
cd andrewmercer.gitlab.io
git init --initial-branch=main
git remote add origin git@gitlab.com:andrewmercer/andrewmercer.gitlab.io.git
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke

Create a basic config

NOTE: the baseurl GitLab provides does not work (CSS doesn’t load), the one I used below does (although it does apparently break the copyright at the bottom left of the footer), see this report

UPDATE: apparently setting baseUrl to ‘https://andrewmercer.gitlab.io’ and adding relativeURLs: true is the better solution as per this update to the bug

cat <EOF >> hugo.yml
baseURL: 'https://andrewmercer.gitlab.io'
relativeURLs: true
languageCode: 'en-us'
sectionPagesMenu: main
title: 'Andrew Mercer'
theme: 'ananke'
EOF

Generate the site content and run the local development server

cd andrewmercer.gitlab.io # need to be in the project root
hugo
hugo server --bind 0.0.0.0 --port 9999
  • access the development server at localhost or your server ip at port 9999 and check it’s working

Follow the guide to host Hugo on GitLab Pages

  • https://gohugo.io/hosting-and-deployment/hosting-on-gitlab

Configure .gitlab-ci.yml

  • https://gohugo.io/hosting-and-deployment/hosting-on-gitlab/#configure-gitlab-cicd
# path: andrewmercer.gitlab.io/.gitlab-ci.yml
variables:
  DART_SASS_VERSION: 1.64.1
  HUGO_VERSION: 0.115.4
  NODE_VERSION: 20.x
  GIT_DEPTH: 0
  GIT_STRATEGY: clone
  GIT_SUBMODULE_STRATEGY: recursive
  TZ: America/Los_Angeles

image:
  name: golang:1.20.6-bookworm

pages:
  script:
    # Install brotli
    - apt-get update
    - apt-get install -y brotli
    # Install Dart Sass
    - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
    - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
    - cp -r dart-sass/ /usr/local/bin
    - rm -rf dart-sass*
    - export PATH=/usr/local/bin/dart-sass:$PATH
    # Install Hugo
    - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    - apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    # Install Node.js
    - curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash -
    - apt-get install -y nodejs
    # Install Node.js dependencies
    - "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
    # Build
    - hugo --gc --minify
    # Compress
    - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec gzip -f -k {} \;
    - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec brotli -f -k {} \;
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Git ignore the public directory and push changes to GitLab

echo "/public" >> .gitignore
git add .
git commit -am "Initial commit"
git push -u origin main

Check the project pipeline status and wait for it to complete build

  • https://gitlab.com/andrewmercer/andrewmercer.gitlab.io/pipelines

Configure custom domain forwarding to GitLab page for Namecheap

  • https://www.namecheap.com/support/knowledgebase/article.aspx/10446/2208/how-do-i-link-my-domain-to-gitlab-pages
  • https://docs.gitlab.com/ee/user/project/pages/custom_domains_ssl_tls_certification/

Add a custom domain for your project’s GitLab Page

  • https://gitlab.com/andrewmercer/andrewmercer.gitlab.io/pages
  • Click New domain
  • Domain: www.andrewmercer.net
  • Certificate: keep at default and allow Let’s Encrypt to manage certificate
    • Note: if the Let’s Encrypt certificate expires, go to your project (e.g. andrewmercer.gitlab.io) => Deploy => Pages => Retry renewal
  • Click Create New Domain

Verify the domain

Once you’ve created the domain, now you need to verify it. GitLab will provide DNS records that you need to add to your DNS provider, in this case Namecheap

Add the ALIAS record

  • First record will be an ALIAS and look like
www.andrewmercer.net ALIAS andrewmercer.gitlab.io
  • In Namcheap, go to your Dashboard, select your domain’s Manage button, select Advanced DNS
  • Select Add New Record, select ALIAS record and contrary to GitLab’s docs, simply put www (leave out the domain.tld part) in the Host field, put andrewmercer.gitlab.io in the Target field
  • Namecheap’s docs state this, but in case you miss it like I did

Add the TXT record

  • Second record will be a TXT record and look something like
_gitlab-pages-verification-code.www.andrewmercer.net TXT gitlab-pages-verification-code=[ some_string ]
  • In Namcheap, while still in Advanced DNS for your domain
  • Select Add New Record, select TXT record and contrary to GitLab’s docs, simply put _gitlab-pages-verification-code.www (leave out the domain.tld part) and put gitlab-pages-verification-code=[ some_string ] in the Value field

Verify domain

Back in your project’s GitLab Pages domain verification status, click the refresh button, it should update and verify the domain

At this point, I am able to go to https://www.andrewmercer.net and get redirected to https://andrewmercer.gitlab.io as well as independently go to https://andrewmercer.gitlab.io.

Troubleshooting

Let’s Encrypt certificate does not auto-renew

If the Let’s Encrypt certificate expires, go to your project (e.g. andrewmercer.gitlab.io) => Deploy => Pages => Retry renewal