Chapter 1

Basics

This is a new chapter.

Introduction

This page was initially created with the command

hugo new --kind chapter basics/_index.md

The kind parameter tells Hugo to start with the templated archetypes/chapter.md which has the contents

+++
archetype = "chapter"
title = "{{ replace .Name "-" " " | title }}"
weight = 1
+++

This is a new chapter.

This just gets us started, we can copy this file out of the theme into our own archetypes directory and add whatever we want. For example I added tags = "chapter" to the chapter pages.

Content Pages

The next steps in the Installation instructions for the Relearn theme is to create content pages 3 different ways. You can click on the tag icon above or go to the tags main page.

hugo new basics/first-content/_index.md
hugo new basics/second-content/index.md
hugo new basics/third-content.md
  • The first creates a directory that can contain more pages (note the underscore index).
  • The second one creates a directory but it can not contain more pages, just images and the like.
  • The last one creates a single page (so not children are possible)

Children

The Relearn theme has a short code to allow me to automatically get a list of the children pages.

Subsections of Basics

Cross Compile Containers

Note

This only works because we cross compile outside the container and copy the results in (notice the FROM scratch and no RUN commands). Otherwise we would also need an emulator to run commands within the container.

Makefile

VERSION   = $(shell git describe --long --tags)
BUILD     = $(shell date +%FT%T%z)
BUILDSYS  = $(shell . /etc/os-release; echo $$PRETTY_NAME)
LDFLAGS   = -ldflags "-X 'main.Version=${VERSION}' -X 'main.Build=${BUILD}' -X 'main.BuildSys=${BUILDSYS}'"
REPOTAG   = rpicreg.home.arpa:5000/gorepo:$(shell git describe)

.PHONY: gorepo-arm gorepo-amd64 build-arm

# normally we only need the version for the Raspberry Pi. (The programs focus)
all: gorepo-arm gorepo-amd64

gorepo-arm:
        GOOS=linux GOARCH=arm GOARM=7 go build -a -tags netgo $(LDFLAGS) -o gorepo-arm .

gorepo-amd64:
        GOOS=linux GOARCH=amd64 go build -a -tags netgo $(LDFLAGS) -o gorepo-amd64 .

build-arm: gorepo-arm
        echo "Tagging arm/v7 with: $(REPOTAG)"
        docker buildx build --platform=linux/arm/v7 --provenance=false --load -t $(REPOTAG) .

Dockerfile

BUILDPLATFORM
matches the current machine. (e.g. linux/amd64)
BUILDOS
os component of BUILDPLATFORM, e.g. linux
BUILDARCH
e.g. amd64, arm64, riscv64
BUILDVARIANT
used to set ARM variant, e.g. v7
TARGETPLATFORM
The value set with –platform flag on build
TARGETOS
OS component from –platform, e.g. linux
TARGETARCH
Architecture from –platform, e.g. arm64
TARGETVARIANT
used to set ARM variant, e.g. v7
FROM scratch
ARG TARGETARCH
COPY gorepo-$TARGETARCH /bin/gorepo
ENTRYPOINT ["/bin/gorepo"]
CMD ["-addr=:8080"]
EXPOSE 8080

Defining the repositories

For configuring the chromebook docker to allow insecure repos, use file: /etc/docker/daemon.json

{
    "insecure-registries" : [
           "rpicreg.home.arpa:5000",
           "camus.home.arpa:5000",
           "localhost:5000"
   ]
}

The config for K2s is /etc/rancher/k3s/registries.yaml

mirrors:
  rpicreg:5000:
    endpoint:
      - "http://rpicreg:5000"
  rpicreg.home.arpa:5000:
    endpoint:
      - "http://rpicreg:5000"

s

Create Hugo in Container

One way that I publish my hugo pages is in a docker container or in my Kubernetes cluster. Both of the places that I run those is on my Raspberry Pi CM3 system which doesn’t have (until recently) a recent version of hugo. To get past this I first have docker to build a development container, load Go and Hugo, and compile the pages. Then I create a second container that doesn’t have the overhead of an operating system or system libraries, copy in the web pages and a web server that has been staticly linked

Note

I have Hugo configured to put the result pages in tht doc directory instead of public. I could simplify the web server if I put in the name of the path that I want to server to use (hugo-demo) in this case. There are other configuration options (relative pages for example) where I could make this build and server even more generic. Someday maybe.

Dockerfile

The first container built is temporary. It starts with Alpine Linux 3.20 which is a small distribution based around Busybox. From the Alpine repository we load go and hugo.

As of 2024-07-15 we get

  • Alpine 3.20.1
  • Go 1.22.5
  • Hugo 0.125.4+extended

The rest sets the working directory, copies all of the local files (our source code) into the working directory. Compiles the pages and compiles the web sever.

The second container starts with an empty container and copies the finished web pages and compiled web server from the first container. The it sets up to start the web server by default with no parameters.

# Container 1
FROM alpine:3.20 AS builder
RUN apk add --no-cache hugo go
WORKDIR /hugo-demo
COPY . /hugo-demo/
RUN hugo
RUN go build -a -tags netgo webserver.go

# Container 2
FROM scratch
WORKDIR /hugo-demo
COPY --from=builder /hugo-demo/doc doc
COPY --from=builder /hugo-demo/webserver webserver
EXPOSE 1313
ENTRYPOINT [ "/hugo-demo/webserver" ]

Build using something like:

docker build -t hugo-demo:latest .

Run using something similar to: (or run as daemon for background operation with -d etc.)

docker run --rm -it -p 1313:1313 hugo-demo [optional-parameters-here]

Web Server

This web server serves up pages from the doc directory. It allows you to put a prefix on the URL to make it easier to configure in a reverse proxy. Allowable values really depends on how Hugo was configured. For example, when I wrote this the configuration was:

baseURL = 'http://www.example.com/hugo-demo/'
relativeURLs = false
publishDir = "doc"

Another valid way to configure Hugo is with:

baseURL = '/'
relativeURLs = true
publishDir = "doc"

Now all of the URLs will be relative. Of course that means that site-map and RSS.xml files will be useless since they don’t have a host to point to. A discussion on these and other ways to configure Hugo is at Theme relearn customizations

Note that the redirect on line 20 was for user convenience. If they go to the root of the website they will be redirected to the top of the documentation.

 1package main
 2
 3// This is a simple web server that serves any file in the current directory
 4// (and below).
 5import (
 6	"flag"
 7	"log"
 8	"net/http"
 9)
10
11var (
12	webAddr = flag.String("web_addr", ":1313", "HTTP service address")
13	prefix  = flag.String("prefix", "/hugo-demo/", "Webpage prefix")
14	dir     = flag.String("dir", "./doc", "Base of documentation directory.")
15)
16
17func main() {
18	flag.Parse()
19	http.Handle(*prefix, http.StripPrefix(*prefix, http.FileServer(http.Dir(*dir))))
20	http.Handle("/", http.RedirectHandler(*prefix, http.StatusFound))
21	log.Printf("Starting Connection on %s\n", *webAddr)
22	log.Fatal(http.ListenAndServe(*webAddr, nil))
23}

First Content

This page was created with the command:

hugo new basics/first-content/_index.md

The _index.md at the end requests that Hugo treat this directory as a collection of other pages (or more branches)

Second Content

This page was created with the command:

hugo new basics/second-content/index.md

The index.md at the end requests that Hugo treat this directory as a leaf page (doesn’t contain other pages) but still allows it to contain other media such as image files.

Third Content

This page was created with the command

hugo new basics/third-content.md

It doesn’t create a directory so it can not contain any other pages or images or …