Generate website with Hugo without installation
Posted on September 9, 2023 • 7 min read • 1,354 wordsHow do I generate a static Hugo website without installing Hugo on my computer?
For this blog, I have opted for a static web project, i.e. the pages are created once and then delivered directly from the web server. To avoid having to create the web pages manually, there are so-called static website generators
such as
Jekyll
,
Gatsby
or the fantastic
Hugo
, which I have chosen.
Static website generators generally have a number of pleasant features:
The great thing about writing a blog is that you can research a topic at any time and prepare it for a short article whenever you come across something interesting.
The most common way is to install Hugo locally on a computer and use the installation to generate the page. So far so good.
I would like to show you an alternative way here that does not require an installation, but is based on a Docker container, which in turn contains Hugo. To make things easier, the main commands are implemented as scripts that then call the container.
All tools are completely free and open source.
I assume you already have Docker installed. If not, there are good introductions out there on the subject of containerisation and how to get started with it (e.g. Docker Docs ).
As an example project, let’s take the Hugo Clarity Theme by Chip Zoller , which I think is very well-designed. If you already have a project, you can of course skip these steps.
On an Ubuntu Linux system, first create a suitable folder and clone the theme into it. The included sample pages are then copied into the template to create a website that can be generated.
mkdir -p ~/project/hugo-clarity/themes
cd ~/project/hugo-clarity
git clone https://github.com/chipzoller/hugo-clarity.git themes/hugo-clarity
cp -r themes/hugo-clarity/exampleSite/* .
The Github project Github Projekt docker-hugo used here is described by its author Erlend Klakegg Bergheim himself as “Truly minimal Docker images for Hugo with batteries included”, i.e. a minimal Hugo Docker image with all the trimmings.
However, we do not need to concern ourselves with creating the image, as you can download the current version klakegg/hugo:0.111.3-ext-ubuntu
(at the time of writing) from
DockerHub
as usual.
For a local installation, the usual procedure would be to start the Hugo server with the parameters -D -E -F -w –disableFastRender in the Hugo project folder.
To do this, Hugo would have to be installed locally. Here we now use the klakegg/hugo image, which does nothing other than make Hugo available in a container, but does it well.
Firstly, some scripts are created. I maintain these little helpers in a ./tools
folder within the Hugo project (parallel to ./config
and ./content
). This folder contains, for example, the tool for starting the Hugo server locally.
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
USER_ID=$(id -u ${USER})
GROUP_ID=$(id -g ${USER})
IMAGE="klakegg/hugo:0.111.3-ext-ubuntu"
SERVER_PARAMETERS=""
PORT="1313"
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
--dev|--development)
SERVER_PARAMETERS+="-D -E -F -w --disableFastRender "
shift # past argument
#shift # past value
;;
--prod|--production)
SERVER_PARAMETERS=" "
shift # past argument
#shift # past value
echo "Production Server"
;;
-p|--port)
PORT="$2"
shift # past argument
shift # past value
;;
-*|--*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
echo "Start Hugo server using: $SERVER_PARAMETERS on port $PORT"
docker run --rm -it\
-u ${USER_ID}:${GROUP_ID} \
-p ${PORT}:${PORT} \
-v ${DIR}/../:/src \
${IMAGE} server -p ${PORT} ${SERVER_PARAMETERS}
The script must be made executable once before it is used for the first time
chmod +x ./tools/hugo-server.sh
The script is executed in a separate terminal window and starts the Hugo server as usual, which then monitors the Hugo project folder, regenerates the project when changes are made and makes it available via a local web server.
Tip
If you use Visual Studio Code as an editor, open a terminal there and start the script there. This way you can see immediately when saving if there were problems when generating.
Usage:
./tools/hugo-server.sh --dev # (development) starts the server using -D -E -F -w --disableFastRender
./tools/hugo-server.sh --prod # (production) starts the server, not showing pages marked as draft
./tools/hugo-server.sh --dev -p 1500 # (development), set local server port to 1500
When started, the output should be similar to this
./tools/hugo-server.sh --dev
Starte Hugo Server mit: -D -E -F -w --disableFastRender auf Port 1313
Start building sites …
hugo v0.111.3-5d4eb5154e1fed125ca8e9b5a0315c4180dab192+extended linux/amd64 BuildDate=2023-03-12T11:40:50Z VendorInfo=hugoguru
| EN | PT
-------------------+----+-----
Pages | 53 | 30
Paginator pages | 1 | 0
Non-page files | 2 | 0
Static files | 63 | 63
Processed images | 0 | 0
Aliases | 30 | 15
Sitemaps | 2 | 1
Cleaned | 0 | 0
Built in 627 ms
Watching for changes in /src/{archetypes,content,layouts,static,themes}
Watching for config changes in /src/config/_default, /src/config/_default/menus
Environment: "DEV"
Serving pages from memory
Web Server is available at http://localhost:1313/ (bind address 0.0.0.0)
Press Ctrl+C to stop
In the event that Docker denies the execution of the script with a permission error
[…] unix /var/run/docker.sock: connect: permission denied.
it could be because the current user is not included in the Docker group.
sudo usermod -aG docker $USER
Now just start a local browser with the url http://localhost:1313/
(or the specified port p
) and the website is already in the browser.
The container and thus the server can be closed in the terminal window with CTRL+C.
The charming thing about the Hugo server is that in development mode (--dev
) it replaces the baseURL
in config.toml
, which normally points to the domain under which the page should run, with localhost:<port (default 1313)>
. This means that the project can only be viewed on the local computer.
At some point, the article will be finished, the right images will be included in the best place and the spelling will have been checked to the best of the author’s knowledge and belief. Now it’s time for the next step towards publication.
The following script generates the Hugo project and thus its web pages (or publishes them in Hugo-speak).
#!/bin/bash
set -e
set -o pipefail
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
USER_ID=$(id -u ${USER})
GROUP_ID=$(id -g ${USER})
# generate the project with Hugo
IMAGE="klakegg/hugo:0.111.3-ext-ubuntu"
# Empty the output folder
rm -rf ${DIR}/../public/*
docker run --rm -it \
-u ${USER_ID}:${GROUP_ID} \
-v ${DIR}/../:/src \
-e HUGO_ENVIRONMENT='production' \
${IMAGE}
Executing the script generates everything necessary for the website in ./public
.
chmod +x ./tools/hugo-generate.sh # run once to make script executable
./tools/hugo-generate.sh
If the content of ./public
is now placed in the root directory of a web server, this will make the static website that has just been created available.
Encapsulating the Hugo static website generator in a Docker container enables it to be used without having to install Hugo and its dependencies on the local computer. This saves the computer from having to install anything. However, it also makes it possible to create identical, generated pages on different computers, as the generating software (Hugo) is encapsulated and versioned in the Docker image.
In order to be able to put the generated static web pages online, a web server is still missing and preferably an integration into an easy-to-publish Docker image.