Perfect Tutorial to Run Hugo with Docker, Nginx and Compose
Posted October 10, 2023
Do you want to build Hugo with Docker? This tutorial uses Docker to package Hugo with Nginx. You’ll also learn to use Docker Compose to run Hugo.
What You Will Learn
Along this comprehensive Docker Guide, you will learn the following:
- How to package a full Hugo app with Docker.
- If you have external frameworks such as Node.js, This Guide will show you how to run them alongside Docker and Hugo.
- Hugo is a static site generator. It fits well with static serves such as Nginx. You will be able to serve the Hugo app with Nginx and Docker.
- If you love working with Docker Compose instead of Dockerfile, you will create a
docker-compose.yml
config to let Hugo run with Docker Compose.
Prerequisites to Running Hugo with Docker
This guide assumes:
- You have Docker installed and running on your computer.
- Basic Knowledge of working with Docker will be essential.
- You must have a running Hugo app. Check this guide to create one. You can also use available Hugo themes to do so.
Why Run Hugo App with Docker
Docker packages your Hugo blog, and you don’t need to configure local environments to have your app running.
On top of that, Docker creates a portable image that you can use to deploy your Hugo app on production.
Let’s dive in and build Hugo with Docker like a PRO.
Running Hugo with Docker and Dockerfile
Dockerfile creates the instructions Docker needs to package any application. In this case, you run Hugo to run on Docker. Therefore, create a Dockerfile
on your project directory as follows:
# Use the base image 'ubuntu:bionic'
FROM ubuntu:bionic
# Update the package repository
# Install necessary packages
RUN apt-get update && \
apt-get install -y \
ca-certificates \
wget && \
update-ca-certificates
# Define the Hugo version
ARG HUGO_VERSION="0.117.0"
# Download and install Hugo
RUN wget --quiet "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz" && \
tar xzf hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
rm -r hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
mv hugo /usr/bin && \
chmod 755 /usr/bin/hugo
## Hugo source code
# Set the working directory to '/src'
WORKDIR /src
# Copy code into the '/src' directory
COPY ./ /src
# Command to run when the container starts
CMD ["hugo", "server", "--bind", "0.0.0.0"]
This Dockerfile is enough to package Hugo. In this case:
- Docker will use
ubuntu:bionic
to run Hugo. - Since this is an Ubuntu distribution Image, you need to update the package repository and install
ca-certificates
andwget
packages, as Hugo will need them. - You need the Hugo version running your application added in
HUGO_VERSION
. - Docker will download Hugo on top of
ubuntu:bionic
. This means it downloads files zipped astar.gz
. This is whereubuntu:bionic
comes into play to extract it and set the appropriate permissions for the Hugo executable. - With Hugo ready, you can set your
WORKDIR
and Copy code files. - Finally, just like you would run Hugo on the local machine, add your command as specified in the
cmd
section.
Build and Run Hugo Docker Container
Ensure you are the root of your project containing the above Dockerfile. On your project directory, run the following command to build your Hugo app:
docker build -t hugo-app .
To access your app, run the following command and create a Docker container to run Hugo
docker run -d -p 1313:1313 hugo-app
Docker will create a container and run your app:
Now you can access your app on http://localhost:1313/
. Here is my sample app:
Use Docker to Package Hugo and Node.js
Hugo has support for Node.js. This means you installed packages that use Node.js and used them on your Hugo app. Therefore. These packages must be accessible to Docker to make your app function as expected:
Below is your ideal Dockerfile to run Node.js and Hugo with Docker:
FROM ubuntu:bionic
RUN apt-get update && \
apt-get install -y \
ca-certificates \
#Node.js and NPM
nodejs \
npm \
wget && \
update-ca-certificates
ARG HUGO_VERSION="0.117.0"
RUN wget --quiet "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz" && \
tar xzf hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
rm -r hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
mv hugo /usr/bin && \
chmod 755 /usr/bin/hugo
WORKDIR /src
COPY ./ /src
# Add package files
COPY package.json package-lock.json /src/
# install Node.js packages
RUN npm install
# Run Hugo site
CMD ["hugo", "server", "--bind", "0.0.0.0"]
This looks like your previous Dockerfile. However, you have added the following:
- Installed Node.js and NPM.
- Added
package.json
andpackage-lock.json
files to your Working directory. - Used command
RUN npm install
node.js packages on your Docker Hugo image.
You can now run the following command to build your Hugo app:
docker build -t hugo-app .
To access your app, run the following command and create a Docker container to run Hugo
docker run -d -p 1313:1313 hugo-app
You should be able to access your app on http://localhost:1313/
.
Running Hugo with Nginx on Docker
If you are looking to use Nginx to serve your stack blog, then here is your sample Dockerfile:
# Use the Nginx Alpine image as a build stage (temporary image)
FROM nginx:alpine as build
# Install wget in the Alpine-based image
RUN apk add --update \
wget
# Define the Hugo version
ARG HUGO_VERSION="0.117.0"
# Download and install Hugo
RUN wget --quiet "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz" && \
tar xzf hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
rm -r hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
mv hugo /usr/bin && \
chmod 755 /usr/bin/hugo
# Set the working directory
WORKDIR /src
# Copy code
COPY ./ /src
# Build the Hugo site
RUN hugo --environment production
# Create a new stage with the Nginx Alpine image
FROM nginx:alpine
# Copy the static website files generated by Hugo from the build stage to the Nginx container
COPY --from=build /src/public /usr/share/nginx/html
In this example:
- You have the first stage, Nginx, to build your image.
- Nginx uses Alpine, which a Linux distribution. It lets you run commands just like you did use
ubuntu:bionic
. - Since you are using an external server, ensure Hugo first builds your site using the
RUN hugo
command. - All the files
RUN hugo
generated are static. So, copy them to Nginx.
To test your Hugo Nginx Docker integration, run the following:
docker build -t hugo-app .
To create a container to ace your app, run the following:
docker run -d -p 1313:80 hugo-app
Note: Unlike the previous example, the above command uses port 80. Nginx is served on port 80. So, your command must bind to the same port.
You will now access your app on http://localhost:1313/
If your image is large, I created this Docker Slim With Minimal Reduce Docker Image Size Strategies for you. Check it out.
Conclusion
Along this comprehensive Docker Guide, you have learned the following:
- How to package a full Hugo app with Docker.
- How to run Node.js alongside Docker and Hugo.
- Used Nginx to server Hugo as static.