🎄First off, Merry Christmas! 🎉

Inspiration

You know when you start doing something new and either want to do it as a learning opportunity or perhaps you want to take notes of it for later? Well why not publish those notes for the world to read? I was inspired by NetworkChuck on YouTube to finally follow through on my idea of writing a blog.

I created the git repository for this project a while ago…

create-repo-timestamps.png

And I have made earlier attempts at doing such a task. Now is the time to start. I have many projects to complete in my life and much that I would like to share in that process.

Why Hugo?

Blogging with Hugo is easy. You write Markdown content, plaintext, and then send it to the static site generator, hugo, and out pops a pretty website that can run on any static host.

We can also complete automate the process of publishing our new site if using something like Github or GitLab as your repository host.

How to Get Started

Installing Prerequisites

First you are going to need to install git and then jump into the Hugo documentation and install both Hugo and Golang.

Since I am on Windows 11, my preferred approach to configuring development tools is Winget. I will write up a short tutorial on Winget in the near future but for now it is the easiest way to get off the ground running here if you are on Windows 11 or newer is:

winget install Git.git Golang.go Hugo.Hugo.Extended

You will need to close your terminal and open a new one prior to using these new commands!

Alternatively, if you are on MacOS or Linux, you get git preinstalled and can install the others with package managers from their OSes.

If you are not on the latest Windows or just do not want to use winget, there are prebuilt packages that you can download and place in your path. Have a look at the Git website for an installer.

At this point you should be able to run hugo --help in your terminal which will give a nice little help text from the Hugo command line interface (CLI) that we just installed. If you got to this point, great! If not, then you will need to double check how you are installing Hugo and Golang with the official documentation.

Creating a Site

Hugo has pretty good documentation on this part but simply you will need to run the new site command and I would recommend using yaml as the format if you are more familiar with that kind of setup or leave it as the default which is toml if you are more of a non-developer type and want a more traditional “config” file type of experience.

You can run the following and replace my site of lowellbuildsit with your site name.

hugo new site lowellbuildsit --format yaml

After that we can ls which lists the directory to see what we have generated.

hugo-structure

Before going any further we should change to that directory we just created and initialize out git repository.

If you have not used git before, you will need to set your user name and user email settings to be able to commit changes. This is so that you can identify who made changes to your repository. Otherwise, skip these two commands.

# This will show on every change you make in git
git config --global user.name "Your name"
# This is to identify you in git
git config --global user.email "[email protected]"

This basically starts a change tracking system in the directory and allows us to publish changes to our choice of git repository servers later. We also make our first commit here. If this is your first commit ever, I am proud of you! 🎉

# change directory (cd) to the directory you generated
cd lowellbuildsit
 # Initializes git's tracking system
git init
# Adds all files and directories in my local directory to git
git add .
# Creates a starting point for git to work from
git commit -m "initial commit"

Picking a Theme

The most stylistic choice you will want to make is to pick a theme. Hugo has a ton of themes to select from, just take a look for yourself over at Hugo’s Official Theme List.

I chose the PaperMod theme which was not the first one on the list but has risen to the top since!

Installing a theme is as easy as deciding what theme, going to its Github and following their instructions to install. In the case of PaperMod, I had to add the repository as a submodule to mine and then add it to the hugo config file.

For example with PaperMod they have the following in their documentation:

git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
git submodule update --init --recursive # needed when you reclone your repo (submodules may not get cloned automatically)

Followed by adding this to your Hugo config:

yaml

theme: ["PaperMod"]

toml

theme = "PaperMod"

Now if we use Hugo’s local server we can verify the website is taking shape. This command will print out some information about the server like what the address and port are, defaults to http://localhost:1313.

hugo serve

To quit this command you can hit Ctrl+C or on MacOS, Command+C

As always, I would recommend committing any changes made here so that you have incremental change tracking which is easier to manager and revert in the event you make a mistake. Before we commit these changes, I would like to introduce you to another useful feature of git, the ignore file. The .gitignore file allows you to tell git not to track certain files and directories. You might ask why and the primary reason is when you are developing anything we often have what are called build artifacts. Build artifacts tend to only be necessary for the final output of your “code” and they change often during the process of development. The nice thing is that they can be regenerated at any point, that means we do not need to track them in git which can save us some weird conflicts and other issues in the future.

touch .gitignore

Open .gitignore in your favorite editor, for me that is VSCode which can be done either by clicking the file or running code .gitignore but for you this may be notepad or gedit for my Linux fans. Add the public/ directory to your git ignore and I also added the hugo lock file used to determine if hugo is running which we do not need saved in the repository.

git-ignore

Now you can add files and commit as expected.

# Adds all files in your current directory to git
git add .
# Commits the changes to git's tracking
git commit -m "Update my hugo theme"

Creating a Post

Now that we have a website structured and have ideas flowing through our minds, it would be good to start writing some down. Hugo uses Markdown as a plain text format to store your posts and content pages in.

There is a lot of differences with each individual theme’s approach to managing content, although the overall majority seem to allow you to put your markdown files straight into the content directory and run from there. PaperMod expects your posts to be inside content/posts so we will make one there.

touch content/posts/first-post.md

Now we can open that and add some front matter.

---
title: My First Post
date: 2024-12-25
draft: false
cover:
    image: first-post-cover.jpg
---

Front matter like this is a markdown supported formatting that tells whatever is reading the file some metadata information about it before proceeding. This helps with formatting the title how you want it, ensuring the date of the post is correct, and even things like draft posts that will not render on your site and adding cover images.

I made a file and dropped a picture next to it called first-post-cover.jpg. From there I added the front matter above and added some plain text to the blog post. This is the result from the homepage of my site.

example-home-page

There is a lot you can do with frontmatter, check out the hugo docs on it.

We should commit these updates again. You know the drill.

git add .
git commit -m

Pushing to a Git Server

This is my second favorite part of the project, publishing to a git repository on the internet (or locally if you host your own). I will not go too in depth on how to create a git repository on your favorite site because there are many providers. If you use GitLab like I do, then you can click the + > new repository, create blank project, and make sure to uncheck “initialize with readme” as that would create an initial commit to our repo that we have already done.

After creating your repository, the steps for most hosts are the same:

  1. Create SSH keys
  2. Add your SSH public key
  3. Add your remote URL to your local git
  4. Git push to your new remote
  5. Verify the files are all pushed as expected to your provider

GitLab and Github have documentation on creating keys to use.

That takes care of steps 1 and 2 above. Now we have a repository and a key to use mapped to our account. On both GitLab and Github, there is a button on the main page of your project called Code that has an option Clone with SSH. We need to copy the url in that option with the convenient copy button then jump back to our terminal.

# Add our repository URL as the "origin" server (this is an alias in git)
git remote add origin [email protected]:lowellbuildsit/hugo-example.git
# Push our local up and track it to the main/master branch (whichever yours defaults to)
git push -u origin master

Take a look at your git provider page for your repository and check you have your files along with the most recent commit message we made.

hugo-example-repo

Using CI/CD to Publish Our Site

This is my favorite part. I do CI/CD more or less for a living so I hope you can understand my excitement momentarily.

In short, this section will walk you through creating a GitLab pipeline (Github has something similar but I am not familiar and will not be covering it here, maybe in the future?) that will take your markdown posts and theme files, build them, and put them up on a public website for the world to see.

In your local repository we will need to add a .gitlab-ci.yml file which is how GitLab tracks its pipelines.

stages:
  - pages

pages:
  image: hugomods/hugo:git-non-root
  stage: pages
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    - hugo build
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
    GIT_SUBMODULE_DEPTH: 1
  artifacts:
    expire_in: 1 week
    paths:
      - public/

We can walk through this file so that you are following what is happening.

  • stages - A list of stages to the pipeline, here we have only one named pages for simplicity
  • pages - A job named pages that will be publishing our site (GitLab requires this name for it to work)
    • image - Docker image we will use, the one listed is a community maintained image
    • stage - Which stage of the pipeline to run in
    • rules - This section tells GitLab when to run our job, here we have whenever your commit is to the default (master/main) branch
    • script - List of commands for GitLab to run in our job, this is the hugo build command that creates our site
    • variables - Environment variables, here we tell GitLab we want it to pull our theme submodule
    • artifacts - What files should GitLab hold onto, hugo publishes to public and for pages to work, we need files in public

That is a lot all at once but it is incredibly powerful and GitLab provides us with free, albeit limited, resources to run this. If we add, commit, and push this file we will get a pipeline one our project page and the final result of a website.

git add .gitlab-ci.yml
git commit -m "Add CI/CD pipeline"
git push

On our project page:

ci-cd-pipeline

Navigate in the side panel to Deploy > Pages and you should see a page with a link to your new website! You can either host it with a unique domain which has pros and cons or use the git URL by deselecting “Use unique domain”. What is truly wonderful about this configuration is that you get 400 minutes a month of free pipeline jobs and with all 6 of my test publishes, I have just hit 1 minute! The other awesome thing is that you can use a CNAME DNS record to point your chosen domain at the site you have just made without needing to pay someone to host it for you. For example, I went in and added a custom domain in the Pages tab https://hugo.example.lowellbuildsit.com/ which now serves the example I just created for thist post!

These are links I believe to be helpful in this whole journey. Some are referenced in the post but others are bonus!