Table of Contents

What is Hugo?

“The world’s fastest framework for building websites.

Hugo is one of the most popular open-source static site generators. With its amazing speed and flexibility, Hugo makes building websites fun again.

Install in seconds, build in milliseconds. Hugo works on macOS, Windows, Linux, FreeBSD, and others.”


Why Hugo?

There are numerous of frameworks available that makes building static websites a lot easier.

It all comes down to ease-of-use and personal preference. With Hugo I had an example site running is minutes with live builds in development mode.

A few alternatives

Of course Hugo is not the only SSG (Static Site Generator) out there, each different generator has its own ups- and downs. After testing out a few SSG’s I setteled on Hugo due to its easy development and deployment cycle.

Here are a few alternatives that caught my eye while developing this blog:


Transform your plain text into static websites and blogs.

No more databases, comment moderation, or pesky updates to install—just your content.

Markdown, Liquid, HTML & CSS go in. Static sites come out ready for deployment.


Eleventy quickly builds speedy web sites. Originally pitched as the JavaScript alternative to Jekyll, Eleventy has matured into a popular modern web site generator.


A next-generation, progressive site generator & fullstack framework, powered by Ruby.

Built upon venerated open source technologies such as Ruby, Puma, and Roda — and grown on the fertile soil of Rails & Jekyll — Bridgetown puts power back in the hands of individuals to create extraordinary things.

Getting started

This section will describe how to get started with Hugo using Docker and Docker-Compose.

Two docker-compose files will be used, one for testing and live building and one for building and deploying for production.

Creating a new website

The following command can be executed to get an Hugo CLI shell docker run --rm -it -v /absolute/path/to/data:/src klakegg/hugo:0.91.2-ubuntu shell.

In the Hugo CLI run hugo new site . to create a new Hugo site in the data directory at /absolute/path/to/data.

File structure



FROM klakegg/hugo:0.91.2-ubuntu

RUN rm -rf /src/public || true
RUN apt update
RUN apt install -y curl
RUN curl -sL | bash -
RUN apt install -y nodejs

RUN npm i @fullhuman/postcss-purgecss
RUN cd /src && npm install package.json


In the test environment the command hugo server will be executed that start the Hugo server with drafts enabled and automatic builds.

version: "3.9"

    build: .
    command: server
    container_name: hugo_test
      - "1313:1313"
      - ./data:/src

The test compose file can be used with docker-compose -f docker-compose-test.yml up --build.

This will run a fully functioning web server at http://localhost:1313 while simultaneously watching your file system for additions, deletions, or changes within the following areas:

  • /static/*
  • /content/*
  • /data/*
  • /i18n/*
  • /layouts/*
  • /themes/<CURRENT-THEME>/*
  • config

Whenever you make changes, Hugo will simultaneously rebuild the site and continue to serve content. As soon as the build is finished, LiveReload tells the browser to silently reload the page.


version: "3.9"

    build: .
    container_name: hugo_build
      - "1313:1313"
      - ./data:/src

The static version ready for public access can be created using docker-compose -f docker-compose-build.yml up --build. This will generate the site to ./data/public that then can be copied to the desired location of a website.

Running hugo does not remove generated files before building. This means that you should delete your public/ directory (or the publish directory you specified via flag or configuration file) before running the hugo command. If you do not remove these files, you run the risk of the wrong files (e.g., drafts or future posts) being left in the generated site.

Moving to public

Since I do not host the website in ./data/public I use a small shell script to move it to the desired location.

The following script will:

  1. clear the current websites content;
  2. Move the built Hugo data to the website;
  3. Clear the Hugo build data;
echo "===--------------------==="
echo "Moving static pages"
echo "/data/public"
echo "to"
echo "===--------------------==="
echo ""

sudo rm -r /path/to/*
cp -r ./data/public/* /path/to/
sudo rm -r ./data/public

Selecting a theme

Customizing the look and feel of Hugo is easy with themes. In ./data there are two important things for theming config.toml and themes/

Inside of config.toml the theme can be selected.

theme = "hello-friend"

This will look for a theme called hello-friend inside of themes/.

Themes for Hugo can be found at

Creating a post using Hugo

The following command, like mentioned above, can be executed to get an Hugo CLI shell docker run --rm -it -v /absolute/path/to/data:/src klakegg/hugo:0.91.2-ubuntu shell

On here you will be presented with hugo:/src$ and the fun can begin!

Run hugo new posts/ to create a new blog-post with the minimal required information. This will create a post in ./data/content/posts/

Drafts do not get deployed; once you finish a post, update the header of the post to say draft: false.

title: "MyFirstPost"
date: 2022-11-06T13:05:51Z
draft: true

Data between --- is the header that Hugo uses as a posts metadata. Below that the actual post can be written using Markdown.

For example:

title: "MyFirstPost"
date: 2022-11-06T13:05:51Z
draft: false
## My first blog post!
Welcome to the first post on my blog!