Plan of Attack

When evaluating options for starting a blog I wanted something that was fast, free, and easy to setup CI / CD for. GitHub Pages ticks both the free and easy boxes but it can be a bit slow to respond. To solve the speed issue I stuck cloudflare in front of GitHub to leverage its CDN caching, ensuring that response times are fast.


Domain Name Provider

I use Hover for my domain name provider, but you can use whatever provider you want. You need to delegate the nameservers for your domain to cloudflare’s nameservers. Under DNS in your Cloudflare Console you’ll see two nameservers assigned to your account. For me they are and


Now that Cloudflare is acting as the nameserver for your domain, we need to configure it to point to GitHub pages and set up caching rules. You can find more detailed instructions on using a custom domain with GitHub Pages here and here. The second link contains list of IP addresses we need to set up as A records in Cloudflare.

GitHub Pages

GitHub pages works for any repository with it enabled, but there is a special repository for each user called {username} that GitHub uses for the corresponding URL of the same name. You need a file called CNAME in the root of project that contains the domain name you’re pointing towards GitHub. Placing it in the {username} repository will let you use that custom domain for the GitHub pages of all your other repositories at https://{domain}/{project-name} for example


To actually generate the site, I decided to go with Hugo which is a very fast static site generator written in Go. You could just as easily use any other static site generator like Next.js if you’d prefer to mess around with React instead. I was going for simplicity and being focused on writing content and not writing components which is why I chose Hugo.

GitHub Actions

To automatically deploy our static site to GitHub pages I’m using GitHub actions which interact really nicely with GitHub pages.

It’s as simple as dropping a file in .github/workflows. This is the current GitHub action script used for this blog.

name: Build and Deploy
      - master
    runs-on: ubuntu-18.04
      - uses: actions/[email protected]
          submodules: true
          fetch-depth: 0

      - name: Setup Hugo
        uses: peaceiris/[email protected]

      - name: Build
        run: hugo --minify

      - name: Deploy
        uses: peaceiris/[email protected]
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public