DEV Community

Cover image for Setup HUGO using Docker
Robin van der Knaap
Robin van der Knaap

Posted on • Updated on

Setup HUGO using Docker

In this article I'm going to describe how to setup HUGO without installing a local version of HUGO on your machine by using a Docker image instead.

When choosing a specific Docker image, be aware that HUGO comes in two editions, standard and extended. The extended edition supports Sass and encoding WebP images, it is recommended by the HUGO team to use the extended edition, and that's what we will do in this article.

We will be using a Docker image from this repository: https://hub.docker.com/r/klakegg/hugo. All Docker images containing ext in its name use the extended edition of HUGO. We will use the Alpine based image.

The Docker image contains the HUGO CLI and exposes the hugo command as the ENTRYPOINT. Running the container and specifying the arguments for the hugo command, gives you all the options you would have when you have HUGO installed locally.

For example, the following command would show the version of HUGO when HUGO is installed locally:

hugo version
Enter fullscreen mode Exit fullscreen mode

The same command can be run using the Docker container:

docker run --rm klakegg/hugo:0.107.0-ext-alpine version
Enter fullscreen mode Exit fullscreen mode

The --rm flag indicates the container is immediately disposed after finishing.

NEW SITE

The following command will generate a new HUGO site called 'test':

docker run --rm -v $(pwd):/src klakegg/hugo:0.107.0-ext-alpine new site test --format yaml
Enter fullscreen mode Exit fullscreen mode

A new folder 'test' will be created, which contains the generated site. The -v flag is used to create a volume from the present working directory (pwd). The --format yaml at the end enables yaml config files instead of toml.

To serve the site, you first need to navigate to the root of the site:

cd test
Enter fullscreen mode Exit fullscreen mode

Run the following command to serve the new site. (notice the added -p flag containing the port numbers):

docker run --rm -p 1313:1313 -v $(pwd):/src klakegg/hugo:0.107.0-ext-alpine server
Enter fullscreen mode Exit fullscreen mode

The site is built in-memory and will be hosted at http://localhost:1313.

You will see a 'Page not found' message when you visit the URL. Let's create an initial page by adding index.html to the layouts folder.

layouts/index.html

<!doctype html> 
<html lang="en"> 
  <head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <title>HUGO & Docker demo</title>  
  </head> 
  <body> 
    <h1>Hello, world!!!</h1> 
  </body> 
</html>
Enter fullscreen mode Exit fullscreen mode

You might need to restart the server to view the changes if your are working on Windows (I have a solution for that in a bit using docker-compose).

docker run --rm -p 1313:1313 -v $(pwd):/src klakegg/hugo:0.107.0-ext-alpine server
Enter fullscreen mode Exit fullscreen mode

And now you will be greeted with 'Hello World' when you visit http://localhost:1313.

DOCKER-COMPOSE

Now instead of running the server each time using Docker run, we can add the server to a docker-compose.yml file and spin up the server with docker compose up. File changes are automatically picked up:

docker-compose.yml

services:
  server:
      image: klakegg/hugo:0.107.0-ext-alpine
      command: server -D --poll 700ms
      volumes:
        - ".:/src"
      ports:
        - "1313:1313"
Enter fullscreen mode Exit fullscreen mode

The -D argument makes sure drafts are also build and served, this is what you usually want during development.
The poll flag is added for Windows users. In cases where Hugo CLI is running in a shared directory on a Linux VM on a Windows host the server is not detecting file changes from the host environment. The polling fixes this problem on Windows. More information here.

EXPOSE HUGO CLI VIA PACKAGE.JSON

Now that we have a convenient way of serving the site, we need a better way to access the HUGO CLI instead of calling Docker run each time. We will create a package.json file for that, and use the scrips section to make the HUGO CLI more accessible.

Create a package.json:

npm init -y
Enter fullscreen mode Exit fullscreen mode

Expose the HUGO CLI by adding the following command to the scripts section:

"scripts": { 
    "hugo": "cross-env-shell docker run --rm -v $INIT_CWD:/src klakegg/hugo:0.107.0-ext-alpine" 
}
Enter fullscreen mode Exit fullscreen mode

'cross-env-shell' is needed for a platform independent way of reading environments variables, such as the $INIT_CWD to get the current working directory.

npm i cross-env -D
Enter fullscreen mode Exit fullscreen mode

Now you call the HUGO CLI like this:

npm run hugo -- --help
Enter fullscreen mode Exit fullscreen mode

CLI arguments are placed after the --.

To build the website you can use the hugo command without arguments.

npm run hugo
Enter fullscreen mode Exit fullscreen mode

The server command as used earlier, builds the site in memory. The build command builds the site and stores the output in the ./public folder.

CONCLUSION

Now you are able to get started with HUGO without installing it on your machine. Hope this helps someone, it took me a few hours to figure this out, especially to get it to work on Windows.

Top comments (0)