Use GitHub Pages to host a Hugo blog on custom DNS


Below is an outline of the steps to set up your blog using Hugo, host it on GitHub Pages, and serve it using a custom DNS. I wrote this for myself, partly to make sense of it all, and partly in case I need to do it again or fix anything.

Make your blog

Follow the Hugo quickstart guide to get a Hugo blog going. Choose a theme, write some content, preview it using the dev server, etc.

Use a canonical name for the folder your blog is in: for this blog, it’s in a folder called blog.mmclar.net.

I’m using a canonical name for my repo, rather than one tied to GitHub/Pages, because it might be hosted somewhere else one day.

When commiting files into git, be sure to .gitignore the appropriate files and folders, especially the public folder where your generated files sit.

State:

  • You should have a local git repository with your Hugo blog

Push your repo to GitHub

Create a new repository on GitHub. Important: this repository must be named <your username>.github.io.

Add the new GitHub repository as a remote for yours:

git remote add pages git@github.com:<username>/<username>.github.io

, and push your repo to the new remote:

git push pages main

State:

  • You should have repository on GitHub called <username>.github.io that is a remote of your repo

Set up Pages

In GitHub, go to the Settings for your new repository. Under Pages, set the source to ‘GitHub Actions’. Find and select the ‘Deploy Hugo site to Pages’ workflow.

State:

  • You should be able to see your blog at .github.io

Set up DNS CNAME

Using your DNS registrar’s tools, add a CNAME entry pointing from the FQDN you want to use for your blog to <username>.github.io.

Back in the Settings -> Pages section of your GitHub repo, add this same custom domain and click Save. GitHub will check the CNAME pointer.

State:

  • You should be able to reach your site without TLS (i.e., via http, rather than https)

Enable HTTPS

In GitHub Settings -> Pages, find and select ‘Enforce HTTPS’.

You may need to re-run deploy because the workflow file defines the base URL including the server and protocol.

State:

  • You should now be able to access your blog via HTTPS