This article will detail how to build a Docker image.

Principle#

  1. Use Hugo to build the site and generate static files.
  2. Use Nginx as the server to handle requests.

Dockerfile#

Create a Dockerfile in the site root.

###############
# Build Stage #
###############
FROM klakegg/hugo:ext-ubuntu as builder

WORKDIR /src
COPY . /src

ARG HUGO_ENV=production
ENV HUGO_ENV=${HUGO_ENV}

# Base URL
ARG HUGO_BASEURL=/
ENV HUGO_BASEURL=${HUGO_BASEURL}

# Module Proxy
ARG HUGO_MODULE_PROXY=
ENV HUGO_MODULE_PROXY=${HUGO_MODULE_PROXY}

# NPM mirrors, such as https://registry.npmmirror.com
ARG NPM_CONFIG_REGISTRY=
ENV NPM_CONFIG_REGISTRY=${NPM_CONFIG_REGISTRY}

# Install dependencies
RUN npm install
RUN npm install -g @fullhuman/postcss-purgecss rtlcss

# Build site
RUN hugo --minify --gc --enableGitInfo

# Set the fallback 404 page if defaultContentLanguageInSubdir is enabled, please replace the `en` with your default language code.
# RUN cp ./public/en/404.html ./public/404.html

###############
# Final Stage #
###############
FROM nginx
COPY --from=builder /src/public /app
COPY deploy/nginx/default.conf /etc/nginx/conf.d/default.conf
  • There are two stages to the build, a build stage and a release stage. The release stage contains only the generated static files, keeping the size of the Docker image as small as possible.
  • If you have defaultContentLanguageInSubdir enabled, please uncomment and modify it on demand.
  • The HUGO_BASEURL parameter is used to specify the baseURL of the site during the build, and is generally used when the baseURL is different from the configuration, so you can remove it yourself if you don’t need it.
  • HUGO_MODULE_PROXY and NPM_CONFIG_REGISTRY are optional build parameters that can be removed if not needed.

Nginx#

Create a deploy/nginx/default.conf in the site root:

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;
    
    root   /app;

    location / {
        index  index.html index.htm;
    }

    location ~* ^/([^/]+) {
        index  index.html index.htm;
        error_page 404 = @error;
    }

    error_page 404 /404.html;
    location @error {
        try_files /$1/404.html /404.html =404;
    }
}

Build#

$ docker build -t mysite \
  --build-arg HUGO_BASEURL=https://example.com \
  .
  • mysite: the image name.
  • HUGO_BASEURL:the baseURL.

For users located in China mainland, you need to specify HUGO_MODULE_PROXY and NPM_CONFIG_REGISTRY to build the image successfully and quickly:

$ docker build -t mysite \
  --build-arg HUGO_BASEURL=https://example.com \
  --build-arg HUGO_MODULE_PROXY=https://goproxy.cn \
  --build-arg NPM_CONFIG_REGISTRY=https://registry.npmmirror.com \
  .

Deployment#

There are many ways to deploy Docker image, such as docker run, k8s, etc. This article will only explain docker run.

Run#

$ docker run \
  -p 2333:80 \
  --name mysite \
  --restart=always \
  mysite

For local testing, you need to change the baseURL parameter or the HUGO_BASEURL build parameter, e.g. http://localhost:2333.

Stop#

$ docker stop mysite

Start#

$ docker start mysite

Remove#

$ docker rm mysite