I recently decided to start playing around with hugo. I’ve been looking for a light weight web framework to build a simple website in. For the style of website i’m going for, React or VueJS seemed overkill to get the job done. I was inspired to try hugo after watching this Luke Smith Youtube Video:

My computer has been infested with a bunch of different frameworks I have tried out. I have React, React Native, Laravel, Svelte. I did not want to dirty up my pc any more.

I found the following docker container, which bundles hugo and it can build out a project for you. The container can be found on the docker registry: hugo-builder

Creating a Hugo project

You must first make sure docker is installed on your system. Dockers installation instructions are here: Docker Installation Instructions

I’m using WSL2 so I used chocolatey to install docker-desktop. To learn more about chocolatey check out their website here: Chocolatey

With docker installed we can generate a hugo project using docker:


docker run --rm -it \
    -v $PWD:/src -u hugo xdevbase/hugo-builder \
    hugo new site jmaguy_hugo

If you’re following along with this guide, replace jmaguy_hugo with whatever you please. This will create a directory with what you decided to give for a name.

Installing and Customizing a Theme

You must choose a hugo theme to style your content. Luckily hugo has a large set of themes readily available: Hugo Themes

I’m choosing the theme terminal. Make sure to follow your chosen theme’s github instructions for installation procedures. To install the terminal theme:


cd jmaguy_hugo # replace with your project name if following along
git submodule add -f https://github.com/panr/hugo-theme-terminal.git themes/terminal
echo 'theme = "terminal"' >> config.toml

If we want to configure the terminal theme, we can copy and paste the following at the bottom of our config.toml file. Uncommenting and flipping the true/false values will modfiy different parts of the theme:


...
[params]
  # dir name of your main content (default is `content/posts`).
  # the list of set content will show up on your index page (baseurl).
  contentTypeName = "posts"

  # ["orange", "blue", "red", "green", "pink"]
  themeColor = "orange"

  # if you set this to 0, only submenu trigger will be visible
  showMenuItems = 2

  # show selector to switch language
  showLanguageSelector = false

  # set theme to full screen width
  fullWidthTheme = false

  # center theme with default width
  centerTheme = false

  # if your resource directory contains an image called `cover.(jpg|png|webp)`,
  # then the file will be used as a cover automatically.
  # With this option you don't have to put the `cover` param in a front-matter.
  autoCover = true

  # set post to show the last updated
  # If you use git, you can set `enableGitInfo` to `true` and then post will automatically get the last updated
  showLastUpdated = false

  # set a custom favicon (default is a `themeColor` square)
  # favicon = "favicon.ico"

  # Provide a string as a prefix for the last update date. By default, it looks like this: 2020-xx-xx [Updated: 2020-xx-xx] :: Author
  # updatedDatePrefix = "Updated"

  # set all headings to their default size (depending on browser settings)
  # oneHeadingSize = true # default

  # whether to show a page's estimated reading time
  # readingTime = false # default

  # whether to show a table of contents
  # can be overridden in a page's front-matter
  # Toc = false # default

  # set title for the table of contents
  # can be overridden in a page's front-matter
  # TocTitle = "Table of Contents" # default


[params.twitter]
  # set Twitter handles for Twitter cards
  # see https://developer.twitter.com/en/docs/tweets/optimize-with-cards/guides/getting-started#card-and-content-attribution
  # do not include @
  creator = ""
  site = ""

[languages]
  [languages.en]
    languageName = "English"
    title = "Terminal"
    subtitle = "A simple, retro theme for Hugo"
    owner = ""
    keywords = ""
    copyright = ""
    menuMore = "Show more"
    readMore = "Read more"
    readOtherPosts = "Read other posts"
    newerPosts = "Newer posts"
    olderPosts = "Older posts"
    missingContentMessage = "Page not found..."
    missingBackButtonLabel = "Back to home page"

    [languages.en.params.logo]
      logoText = "Terminal"
      logoHomeLink = "/"

    [languages.en.menu]
      [[languages.en.menu.main]]
        identifier = "about"
        name = "About"
        url = "/about"
      [[languages.en.menu.main]]
        identifier = "showcase"
        name = "Showcase"
        url = "/showcase"

Running the Site

Running and deploying your site is easy, thanks to docker. To serve your webpage run the following docker command:


docker run --rm -it \
    -v $PWD:/src -p 1313:1313 \
    -u hugo xdevbase/hugo-builder \
    hugo server -D -w --bind=0.0.0.0

See your webpage displayed here: Your New Hugo Page. Any new changes to your website, the server should autoreload.

Add a post

Adding a post is streamlined through docker.

To create a post:


docker run --rm -it \
    -v $PWD:/src -u hugo xdevbase/hugo-builder \
    hugo new posts/my-first-post.md # replace with your desired name
This should generate a new markdown file in:

content/
   posts/
      my-first-post.md

You can start editing that file and writing markdown. If you need a markdown refresher: Hugo Markdown

Another thing to note is that Hugo uses the Goldmark markdown parser. Make sure to set draft to false to see your posts appear on the webpage.