a73x

high effort, low reward

← Posts

Building a Static Site with Hugo and Docker

Table of Contents

This will be a quick walkthrough of how to create a static site using Hugo, and use Nginx to serve it.

Prerequisites

Skill Description
Basic Terminal Usage Familiarity with navigating directories and running basic commands in a terminal.
Git Ability to initialize a Git repository, commit changes, and interact with remote repositories.
Markdown Knowledge of writing basic content in Markdown format (used for posts).
Docker Basics Understanding of Docker commands for building images and running containers.
HTML/CSS Basics General awareness of HTML and CSS for customising static site content.
Go Go should be installed on your system to use Hugo with the go install method. Alternatively, you can download Hugo binaries directly or use a package manager.

Step 1: Installing Hugo

Hugo is a static site generator, meaning it builds HTML, CSS, and JavaScript that doesn't need a backend server, since the website's content is static.

You can install Hugo in multiple ways. If you already have Go installed, you can use

go install github.com/gohugoio/hugo@latest

Alternatively, you can install Hugo following the official install guide>

Step 2: Creating a New Hugo Site

To create a new Hugo site, run:

hugo new site website

This creates a new folder called website with the basic structure of a Hugo site.

Step 3: Setting Up a Theme

By default, Hugo doesn't ship with any themes installed, so its likely you'll want to add one. A list of pre-made themes exist here, which saves you from having to create one from scratch. Typically, this involves using a Git submodule to manage the theme:

cd website
git init
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

A Git submodule is a way to link a separate repository (the theme) into your project without copying it directly. This keeps the theme up-to-date and lets you manage it separately from your main website's content.

To use the theme, add it to your config.toml file:

echo 'theme = ["PaperMod"]' >> hugo.toml

Alternatively, you could manually download the theme and place it in the themes folder, but using submodules allows for easier updates.

Step 4: Personalising Your Site

Open config.toml in your favorite code editor (e.g., VS Code), and change the title line to peronsalise your site's name:

title = "<insert name>'s blog"

This will update the title of your site, which you’ll see when we generate the site in a moment.

Step 5: Creating a New Post

To create a new post, run the following command:

hugo new content content/posts/my-first-post.md

This will create a new file in the content/posts directory, named my-first-post.md. When you open it, you’ll see:

+++
title = 'My First Post'
date = 2024-09-08T15:44:30+01:00
draft = true
+++

The block of text wrapped in +++ is called "front matter" and acts as metadata for your post. It won't be visible in your generated website, the actual content of your post goes below this.

Now, you can edit the file to include your first post:

+++
title = 'My First Post'
date = 2024-09-08T15:44:30+01:00
draft = true
+++
## Welcome! 

This is my first post on my new site. It's written in markdown and utilises hugo for generating html which browsers understand and can parse.

Visit the [Hugo](https://gohugo.io) website!

Step 6: Previewing Your Website

To preview your website locally, run the following command:

hugo server --buildDrafts

This will start a local server, and you can view your site by visiting http://localhost:1313 in your browser.

Step 7: Publishing the Website

Once you're ready to publish, update your post by changing draft = true to draft = false (or just delete the draft property) and run:

hugo

This will build your site and place the generated files in the public folder. This folder contains all the HTML, CSS, and JavaScript that make up your static site.

From here you can deploy it following [Hugo's own guide](https://gohugo.io/categories/hosting-and-deployment/. However, most of these options involve using someone else's compute, and our goal here is self hosting.

Step 8: Dockerising your Site

Now that you have a static site in the public folder, let's create a Docker image that will serve your site using Nginx, a lightweight web server. While you could install Nginx directly on a server and follow this guide to deploy your site, using Docker offers several advantages. Containers provide a reproducible, isolated environment that makes it easy to package, run, and deploy your site across different systems. So, let's use Docker to handle serving your site instead.

Create a Dockerfile with the following content

FROM nginx:1.27.1
COPY public /usr/share/nginx/html

This tells Docker to use the official Nginx image and copy the files from your public folder (which Hugo generated) into the default location that Nginx serves from.

Step 9: Building and Running the Docker Image

To proceed, you'll need a container registry. We'll use Docker hub for this example (you'll need an account) but you can use whatever container registry you have access to.

To build your Docker image, run:

docker build . -t <dockerusername>website:0.0.1

Here:

Now that you have the Docker image locally, you can run it using

docker run -p 8080:80 <dockerusername>website:0.0.1

Here, -p 8080:80 maps port 8080 on your local machine to port 80 in the Docker container, where Nginx serves the content.

Now, open a browser and go to http://localhost:8080. You should see your static site served by Nginx!

But your server is not your local machine (potentially), so you need a method of getting the image from your local machine, to your server. We can use container registries as an intermediary.

  1. First login to Docker Hub:
docker login
  1. Push your image to Docker Hub, by default this image will be public.
`docker push <dockerusername>website:0.0.1
  1. SSH into the server
ssh user@server-ip
  1. Pull the Image (we don't need to login since the image is public):
docker <dockerusername>website:0.0.1
  1. Run the Docker Image
docker run -d -p 80:80 <dockerusername>website:0.0.1

You will be able to access the website by visiting http://server-ip:80

Conclusion

Congratulations on creating and running your first static website with Hugo and Docker!