Deploying Hugo to

Deploying Hugo to requires a webserver, for this we will use NGINX. Continuing from Hugo + Alpine.js + TailwindCSS Quickstart and Integrating we will update the Dockerfile in our project by adding two addition stages, builder and release.

The builder stage extends our hugo image and run the npm run build npm script that will trigger the Hugo production release, saving the output to /src/public/.

The release stage uses an nginx:alpine docker image and copies in the files in /src/public/ from the builder stage and a custom nginx.config.

# hugo/Dockerfile
# ...

FROM hugo as builder


RUN npm run build

FROM nginx:alpine as release
COPY --from=builder /src/public /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf

The nginx.conf we will use is pretty bare bones for this example, it listens on’s default port 8080, serves the static files and handles any 404 errors with Hugo’s 404 page.

# hugo/nginx.conf

user nginx;
worker_processes auto;

events {
  worker_connections  1024;

http {
  server {
    # `8080` is the defalt port uses
    listen 8080;
    listen [::]:8080;

    # the domain name of the server
    server_name _default;

    # prevent using `http` or `https` and server name in the redirect url
    absolute_redirect off;

    # do not use the port in the redirect url
    port_in_redirect off;

    # the folder for the Hugo output
    root /usr/share/nginx/html;

    # use `index.html` as the default page
    index index.html;

    # use the Hugo 404 page
    error_page 404 /404.html;

Now we can change into the ./hugo folder and run fly launch to create our new app, or fly deploy to push a new release.

Because we are referencing a the HUGO_OPENGRAPH_KEY and HUGO_OPENGRAPH_SECRET environment variables at build time we need to leverage the --build-arg flag when running fly deploy.

cd hugo

# store the env variables in the context of the fly command
source .env

# Use `fly launch` with `HUGO_OPENGRAPH_KEY` and `HUGO_OPENGRAPH_SECRET` to create your Fly App
# fly launch \

# Use `fly deploy` with `HUGO_OPENGRAPH_KEY` and `HUGO_OPENGRAPH_SECRET` to deploy new versions
fly deploy \

You should now have a Hugo site being served by NGINX running on

If you’re using Cloudflare you will run into a “Failed to find a valid digest in the ‘integrity’ attribute for resource” if you use the “Auto Minify” feature for your JavaScript. The feature is not needed since we are using Hugo’s -minify flag when building our site.