Hugo in Docker

When I first started using/testing Hugo, I was using a Linux virtual machine to run it.

After I decided to use it, I wanted to move it from needing a full virtual machine to a Docker container.

This was especially important, given the nature of Hugo, as a minimal application that doesn't require a lot of resources.

Going from a dedicated Linux box to a Docker container was pretty easy, given that there was already a Docker image created for Hugo.

Erlend Klakegg has done a great job building Docker images for a variety of Hugo installs, which includes Hugo, and Hugo Extended version.

There is the minimal-install Busybox install, and other base images, depending on what the user wants out of Hugo, and what they want to be able to do inside the Docker container.

For my uses, I use the awscli to deploy this site to my AWS S3 bucket, so I went with the Hugo Extended, build off of Ubuntu.

Getting the Docker container up and running is easy, but if you don't have an existing site, you have to jump through a couple of small hoops to get it to run, based off the Docker image I'm using.

Docker with an existing Hugo site

With my Hugo website being located in /mnt/hugo/, my hugo.yaml file would look like this:

server:
    container_name: hugo
    image: klakegg/hugo:ext-ubuntu
    #image: klakegg/hugo:0.88.0-ext-ubuntu
    command: server
    volumes:
      - "/mnt/hugo:/src"
    ports:
      - "1313:1313"

With this above hugo.yaml file, the Docker container was created using this syntax:

docker-compose -f ./hugo.yaml up -d

Docker without an existing Hugo site

Without an existing Hugo site, or specifically, without a config.toml file, the Hugo Docker container exits after running.

Looking at the logs tells us it's looking for the config file, but then we're in a cirucular argument, as we can't create the config file until the server is up and running . . .

docker logs hugo
Error: Unable to locate config file or config directory. Perhaps you need to create a new site.
       Run `hugo help new` for details.

The workaround is to create a simple config.toml file, so the Hugo Docker image will run, then from within the Docker container, initiate a Hugo site.

In the same directory as your hugo.yaml file, create a file config.toml, and add these lines:

baseURL = 'http://example.org/'
languageCode = 'en-us'
title = 'My New Hugo Site'

Now run the docker-compose -f ./hugo.yaml up -d command, and the Hugo container will remain running.

Access the Hugo container, and create a new Hugo site:

docker exec -it hugo /bin/bash

root@8a23e75ae1ae:/src# ls
config.toml  hugo.yaml  resources

root@8a23e75ae1ae:/src# hugo new site mysite4
Congratulations! Your new Hugo site is created in /src/mysite4.

Now on the Docker host, we can see the approriate files and directory layout:

tree mysite4
mysite4
├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes

6 directories, 2 files

At this point, proceed with your newly created Hugo site.

After Hugo container creation

After creation, verify it's up and running:

docker ps
CONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                PORTS                                                 NAMES
b8db7bf9624c   klakegg/hugo:ext-ubuntu           "hugo server"            59 minutes ago   Up 59 minutes         0.0.0.0:1313->1313/tcp, :::1313->1313/tcp             hugo

Get the version of Hugo:

docker exec -it hugo hugo version
hugo v0.88.0-ACC5EB5B+extended linux/amd64 BuildDate=2021-09-02T11:51:42z VendorInfo=hugoguru

From there, it was easy enough to install the awscli package, configure it, and deploy my site.

docker exec -it hugo apt update
docker exec -it hugo apt install awscli -y

Notes:

  • About the only thing I changed from the base yaml file was to add the container_name and a comment about the latest version that is working.

  • I've discovered that the comment about the latest working version is important, as updates can/might break something in the future, so it's a good idea to have a working version number to fall back on.

References

dockerhub - klakegg/hugo https://hub.docker.com/r/klakegg/hugo/