Starting a Blog - Part 1: Hugo

This is the first of several posts that will discuss how to set up a new blog using Hugo and Netlify. I will discuss the steps taken to create this blog and publish it to a custom domain.

I decided to start a blog with the two goals to:

  1. learn new things about programming and Go in particular; and
  2. pass along what I’ve learned to others starting to use Go.

While I could have used a blogging service or well established tools like Wordpress, I decided to self host my blog using Hugo and Netlify. This first series of posts will detail my setup to bring my blog to life from scratch.

What is Hugo?

Hugo is a static website generator written in Go. It provides a means for creating a website built wholely from pregenerated files. In other words, there is no need for a database or other resources to serve your website, just a standard web server. By focusing on static content, Hugo makes deploying and maintaining a small website like a blog quite easy. It also reduces the server-side requirements to host, allowing for cheap (or even free) hosting of Hugo sites by companies like Netlify.

Installing Hugo

I run Ubuntu Linux at home and it is quite easy to install Hugo via the standard apt get packaging tools:

sudo apt-get install hugo

However, for Ubuntu 18.04 LTS (‘Bionic Beaver’), the version of Hugo installed from the standard Ubuntu package repository is 0.40.1 which is somewhat old (released in April of 2018). To get a more up to date version we can directly download a .deb package from Hugo’s github releases page and install manually. (I’ve chose v0.55.6 as it is pretty recent without being cutting edge):

jbowen@maranello:~$ wget
2019-08-23 10:39:28 (437 KB/s) - ‘hugo_0.55.6_Linux-64bit.deb’ saved [8454508/8454508]

Before installing do a double check of the file by computing the SHA256 checksum of the downloaded .deb file and comparing to the value in

jbowen@maranello:~$ sha256sum hugo_0.55.6_Linux-64bit.deb
afab8eaf12a9d72a072288f4ec5012cd889374cd56a855639b6ee1ba1686d174  hugo_0.55.6_Linux-64bit.deb

This matches the recorded checksum so we can go ahead and install using dpkg:

jbowen@maranello:~$ sudo dpkg -i hugo_0.55.6_Linux-64bit.deb
Selecting previously unselected package hugo.
(Reading database ... 223205 files and directories currently installed.)
Preparing to unpack hugo_0.55.6_Linux-64bit.deb ...
Unpacking hugo (0.55.6) ...
Setting up hugo (0.55.6) ...

Creating Blog Skeleton

Once installed, you can use the hugo command line tool to create the skeleton for a new site, via the command:

jbowen@maranello:~/blog$ hugo new site
Congratulations! Your new Hugo site is created in /home/jbowen/blog/

Just a few more steps and you're ready to go:

1. Download a theme into the same-named folder.
   Choose a theme from, or
   create your own with the "hugo new theme <THEMENAME>" command.
2. Perhaps you want to add some content. You can add single files
   with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
3. Start the built-in live server via "hugo server".

Visit for quickstart guide and full documentation.

Now the directory, blog/, will contain all our necessary content (ie. blog posts, about page, etc) as well as necessary theme and formatting information required for our blog.

Create a Git Repo

In order to track our changes (as well as to interface with the Netlify deploy tooling), we will initialize a new git repository for this directory and then make a commit of the basic skeleton as an initial baseline:

jbowen@maranello:~/blog$ git init
Initialized empty Git repository in /home/jbowen/blog/
jbowen@maranello:~/blog$ cd
jbowen@maranello:~/blog/$ git add .
jbowen@maranello:~/blog/$ git commit -m "Initial commit - basic Hugo skeleton"
[master (root-commit) 50d7b92] Initial commit - basic Hugo skeleton
 2 files changed, 9 insertions(+)
 create mode 100644 archetypes/
 create mode 100644 config.toml

You can note that while hugo create a few directories, git only committed two files. This is because git only handles files and does not track empty directories.

Installing a Theme

Before we can generate a website, we need to chose a theme. There are many Hugo themes available online (see for a showcase of many popular themes). I chose to go with a more simple theme, Hyde, as I found it included much of what I was hoping for and I would only need to make minor adjustments to use it for my blog.

Themes are installed by copying the theme files into an appropriately named subdirectory under the /themes folder in your site root directory. Since we are using git and the theme is stored on github, we can use git submodules to embed the theme content into our local repository while still being able to track and update the theme directory to any changes made in the main repo on github.

jbowen@maranello:~/blog/$ git submodule add themes/hyde
Cloning into '/home/jbowen/blog/'...
remote: Enumerating objects: 388, done.
remote: Total 388 (delta 0), reused 0 (delta 0), pack-reused 388
Receiving objects: 100% (388/388), 832.64 KiB | 1.69 MiB/s, done.
Resolving deltas: 100% (182/182), done.

Once installed we modify our config.toml file to point to our theme using the theme directive by adding the following line:

theme = "hyde"

Creating your first blog post

The final step before we can generate our first test site is to actually add a post. Hugo simplifies this through the hugo new command. Create a new post named ‘Welcome’ by running the following command:

jbowen@maranello:~/blog/$ hugo new posts/
/home/jbowen/blog/ created

This will create a new file named content/posts/ and pre-fill some TOML formatted metadata (what Hugo calls front matter) in the markdown file:

title: "Welcome"
date: 2019-08-19T19:19:58-07:00
draft: true

Front Matter

Hugo uses this front matter when generating its web pages. These default entries are relatively straightforward to understand. The exception might be the draft entry which is used by Hugo to indicate whether a post should be published by default. By marking the file with draft: true the post will not be published when the site is generated, allowing one to keep in-process work in the git repository without prematurely publishing it.

Hugo has a lot more front matter options. More documentation can be found here.

Writing Content

The actual content within a post is written in Markdown syntax, a lightweight markup language that Hugo will use to generate HTML in the final site. This allows site owners to concentrate on the actual content of the website without having to worry about all the details of HTML and the like.

For our first post, simply append the following to the file created above and save it:

*Hello stranger!*
Welcome to my little corner of the online world.

Testing the site

Not only does Hugo generate a static web site from your content, it also can be used to view your website locally during development. Running hugo server from within your blog directory will start a local web server with a current version of your web pages:

jbowen@maranello:~/blog/$ hugo server -D

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

Total in 6 ms
Watching for changes in /home/jbowen/blog/{content,data,layouts,static,themes}
Watching for config changes in /home/jbowen/blog/
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at //localhost:1313/ (bind address
Press Ctrl+C to stop

The -D option will include draft posts when generating the site so you can see how they will appear prior to actually publishing. Once the hugo server is running, you can view your site by accessing it in a browser through the URL in the message above (ie. http://localhost:1313). While there will not be any posts, you should see the basic framework of the themed website:

The best thing (IMHO) about the hugo sever is that it is a ‘live’ presentation of your content and will automatically reload when it detects changes. Thus, you can have a browser window open while editing a post or config file, and then see the changes be applied as soon as you press save. Awesome.

Wrapping Up

This concludes my first posting on setting up my blog. In the next post I will discuss modifying the appearance of the blog by configuring and overriding settings of the theme.