Setting Up a Blog on Github Pages in Under 90 Minutes

July 21, 2021

How can you be sure you understood a certain concept?

All of the above is certainly part of gaining understanding in a new area. But for me one thing has proven to be the ultimate proof, the litmus test: Explaining the concept to fellow human beings in such a way that they feel like they understand it.

A TIL ("Today I Learned") blog is one possibility of sharing knowledge - in fact just one single piece of knowledge that you learned on a given day. I wanted to set up such a blog with GitHub Pages, and here is how I managed to do it in a reasonable amount of time.


One word of background (and maybe caution) beforehand: I am a CloudOps kind of person, so:

This might explain the following points:



We will set up two repositories:

  1. The build repo is going to house the Hugo site from which the site is going to be generated.
  2. The content repo is going to be the one from which the generated files are going to be served via GitHub Pages.

GitHub Pages offers two types of sites: user/organization sites and repository sites. I chose the user site, so my domain is going to be

The full plan goes like this:

  1. Set up the repositories
  2. Run the Hugo setup
  3. Enjoy your site is set up and start writing posts 😊

1. Set Up the Repositories

1.1. Create the Repositories

Create the repos in GitHub

1.2. Configure GitHub Pages for the Content Repo

This step is probably not completely necessary in this kind of setup, but do it anyway to verify:

  1. Open your content repo in GitHub.
  2. Open Settings > Pages
  3. The settings page should show a green box stating that ...

βœ… Your site is published at https://{domain}/

1.3. Enable Deployment With Deploy Key

Your build repo is not automatically allowed to push commits to the content repo. For this to work, you need to create an SSH key and paste the corresponding parts into the repo's settings.

  1. Create an SSH key
    • Execute ssh-keygen -N '' -f deploy.key - this will create two files:
      1. deploy.key: the private key
      2. the public key
  2. Set up the secret in both repos
    1. Open the content repo > Settings > Deploy keys
      1. Hit "Add deploy key" (upper right).
      2. Name it e.g. hugo-deploy in the Title field.
      3. Paste the contents of into the Key field.
    2. Open the build repo > Settings > Secrets
      1. Hit "New repository secret" (upper right)
      2. Name it ACTIONS_DEPLOY_KEY in the Title field.
      3. Paste the contents of deploy.key into the Value field.
  3. As you can always generate new keys to connect the repositories, you don't have to save the keys anywhere after this.

2. Set Up the Hugo Site in the Build Repo

2.1. Basic Setup

🚨 Please don't blindly execute this! First, do the following:

  1. Choose a theme.
    • ⏳ You can spend a substantial amount of time at this point, so you might want to set yourself a timer if you want to stay within the 90 min window πŸ˜‰
  2. Adjust the variables:
    • GH_USERNAME should be your GitHub username
    • BUILD_REPO should be the name (not URL) of your build repo
    • THEME_URL should be the URL of your theme
# Install Hugo
brew install hugo

# Create a new site
hugo new site "$BLOG_NAME"

# Initialize a Git repo
git init
git remote add origin$GH_USERNAME/$BUILD_REPO

# Install theme
git submodule add "$THEME_URL" themes/"$(basename $THEME_URL)"

2.2. Health Check

Let's check if you can build your project locally:

## Load example site content
# NOTE: The following instructions are specific to the theme I chose!
rm -i config.toml
cp themes/hugo-theme-stack/exampleSite/config.yaml .
cp -r themes/hugo-theme-stack/exampleSite/content/* content

## Start server
hugo server
# TODO: Open http://localhost:1313
# -> This should look like
# TODO: If it does, quit the server with Ctrl+C

# Remove sample content (apart from pages)
find content -mindepth 2 -type d -not -name "*page*" -exec rm -i {} \;

2.3. Create the First Post

hugo new post/"$POST_NAME"/
# Remove draft status so the post becomes visible
sed -i '' '/draft: true/d' content/post/"$POST_NAME"/

2.4. Add GitHub Action

The GitHub Action is going to perform the Hugo build.

⚠️ This is the only file that I am taking directly from my (already set up build repo). It is based on the example from the official Hugo tutorial on GitHub Pages hosting.

🚨 Before executing remember to set CONTENT_REPO to the name of your content repo.

curl \
  -o .github/workflows/gh-pages.yml
# Replace content repo URL
sed -Ei '' "s/external_repository: (.*)/external_repository: $CONTENT_REPO/" .github/workflows/gh-pages.yml

# Configure site base URL
sed -Ei '' "s#baseurl: https://(.*)#baseUrl: https://$CONTENT_REPO#" config.yaml

2.5. Commit and Let the Magic Happen

# Add gitignore
curl -o .gitignore

# Perform initial commit
git add .gitignore .gitmodules .github archetypes content themes config.yaml
git commit -m "feat: set up hugo site w/ theme & test post"
git push

Now open your site's domain in the browser. Hugo is fast (and GitHub Actions isn't slow either), so you should see your site appear in less than 3 minutes! πŸš€

Appendix: Use a Custom Domain

GitHub Pages allows you to use your site with any custom domain you own (either from the root domain or from a subdomain). I have not included the procedure in this guide as I don't own any domain and DNS changes can take up to 24 hours to propagate (thus going beyond the 90 minute limit I set myself).

If you are interested in using your own domain, consult the documentation.


This post showed how to set up a Hugo blog on GitHub pages in less than 90 minutes.

Originally I wanted to call this post "How to set up a TIL blog on GitHub Pages in under 1 hour", but (you probably guessed it) it took me a bit longer than that. However, with the playbook I provide in this post, you might be a lot faster than I was!

About the author: Josia Scheytt

Loves automating, especially to help fellow engineers. Passionate about Kubernetes, databases, and living the DevOps life in unsiloed teams.

Join us