I created a blog on the interwebs back in 2019 while working at The Boeing Company. I had internal Mattermost channels and social sharing groups where we shared information but a lot of my eureka moments were too niche for the bigger company audience. We were doing a lot of interesting things and constantly hitting the same odd issues over and over. I realized googling helped piece specific issues together over time but never had a straight forward answer. I thought it would be handy to create a wordy blog that could be indexed properly that contained these specific problems. If it helps one person, I’d consider it a success.

The first blog I went with was a Ghost setup made for Heroku. It wasn’t a container but one of their one-click offerings (if I recall correctly). It did a great job for a year and half. Unfortunately, it did cost me $7 a month to use the tier that allowed custom domains. I didn’t mind, it did a great job and was always available when I needed it.

Fast forward months later.. I noticed I kept getting a bunch of subscribers to the email service. A bunch of bot emails based in Gmail and some giveaway emails that automate something about your post. I trimmed it on and off but decided I didn’t care any more.

Fast forward to the return of the Bald Bearded Builder on Twitch.. I offered up this blog when he was reviewing viewers' blogs. To my dismay, it was half broken. Luckily, I had started down the right of passage “Make your own blog” in 2020 before I left The Boeing Company. Unfortunately, I tabled it as I transitioned jobs but still had a desire to improve it. This was the push I needed and went through the process just the night before.

If you have read this, then moving it was a success. We used Hugo a few times at Boeing to help generate some documentation. I enjoyed the workflow when properly set up to CICD. Like now, I am just writing markdown in VS Code and will commit and push this update to Github and it will deploy in a few minutes.

No images, no ads, no extra garbage. Just some good ol' helpful information.

What we’re doing

  • Set up a Github Repo
  • Set up a Hugo environment on Windows
  • Set up an Azure Static Web App
  • Set up a Github Action using Azure Static Web Apps

Set up a Github Repo

Create your repo. Nothing special. You will connect to your Github profile from Azure later to provision everything for you.

Hugo Environment on Windows

Hugo runs as a CLI wherever you use it. In my case, I’ll be using it on Windows. The workflow should be the same whether you’re on a Mac, Linux, Docker..

Refer to https://gohugo.io/getting-started/quick-start/ for accurate info.

Download the Hugo binary

The CLI will handle generating your project, provisioning additional items, and building the dev and prod outputs.

Stick it wherever you prefer. Be sure to add it to your environment variable Paths.

Provision a project

Navigate to your project folder and run the following:

hugo new site .

This will create the project at the root. It expects a relative path: hugo new site {path}

Your project file will be the config.yml or config.toml at the root. I chose to use yaml. From here I’ll refer to it as the config file.

If your project folder is not empty, you can use –force

Use hugo help to see more cli info

Pick a theme

Visit themes.gohugo.io

Consider the different ways you can deploy a theme using the docs from the one I use: Papermod

The one consideration I would recommend is manually pulling before the CICD pipeline runs. You can run the latest submodule code every time you push but introduces potential problems.

Either way, you should have a theme project folder in the themes folder. Take note of the theme project folder name.

Set your theme in the config file by adding or altering theme: ThemeProjectFolderName. In my case, it is theme: PaperMod. If the theme element doesn’t exist, simply add it as a root level element in the file. Mine looks like this:

baseURL: "https://www.bitobrian.com/"
title: Brian Donaldson - bitobrian
paginate: 5
theme: PaperMod

Paginate limits the list number of blog posts per page on this site.

Write your first post

From your project root, you can run the following to generate a new post markdown file:

hugo new posts/my-first-post.md

Inside this file, it will generate a subset of metadata that describes your blog:

title: "My First Post"
date: 2022-02-03T19:29:56-06:00
draft: true

The cool thing about this for me was the ability to back date my blog posts as I migrated them without doing database work.

Below that last dash line, you can begin your markdown post. When you’re done simply save it and we’ll go on to see how it looks.

Run dev

The Hugo cli has a dev server built-in that monitors files and reloads on the fly. Run the following from your root to crank it up:

hugo server

You’ll get an output like this:

Start building sites …
hugo v0.92.1-85E2E862 windows/amd64 BuildDate=2022-01-27T11:44:41Z VendorInfo=gohugoio

                   | EN
  Pages            | 57
  Paginator pages  |  1
  Non-page files   |  0
  Static files     |  0
  Processed images |  0
  Aliases          | 21
  Sitemaps         |  1
  Cleaned          |  0

Built in 124 ms
Watching for changes in C:\path\project\{archetypes,content,data,layouts,static,themes}
Watching for config changes in C:\path\project\config.yml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender

That’s it! You have a local dev workflow ready to go!

If you want to run a production output, you can use hugo -D and it will generate static files in the public folder.

Set up an Azure Static Web App

Head over to the Azure portal and search up Static Web Apps.

I’d assume at this point you might have a little Azure knowledge. If you don’t, you should know you will need a Resource Group created to place this resource in. It’s just a group container of things you’ll use together. It’s handy.

In the Static Web Apps panel, click create.

In the Create Static Web Apps panel, you’ll need to specify your subscription and resource group. From there, give it a name, choose your hosting type, and select a region.

Here’s the best part: In Deployment details, select Github and sign in. After selecting your repo and branch, you can select the Build Preset Hugo.

From here, it will provision your service and provision a Github action that will build and deploy automatically. That action will contain the bits needed to execute hugo commands and take the output to the service. Pretty awesome!

Microsoft uses Oryx to accomplish this. Cool beans.

That’s it

If you go back over to Github, you should see your action and it’s first run. The action yml will be in your repo now so you can adjust it as needed. I didn’t have to do anything for my needs as it works great.

Bonus Custom Domain

If you don’t know, you can add a custom domain that includes an SSL certificate using your domain name provider. It’s as easy as updating your dns records to prove ownership and add an alias or cname.

Let me know if this helped you. I’m @bitobrian on Twitter. Feel free to sound off and let me know.