Hugo docker + nginx proxy manager docker (solved)

I’ve managed to run hugo on docker thanks to @razon on this other support post.

Now I’ve “managed” to run it behind nginx proxy manager, but I fail to understand how I generate the contents of the public folder using the nextcloud docker.

I run hugo like this:

docker run -p 1313:1313 \
  -v ${PWD}:/src \
  hugomods/hugo:latest \
  hugo server --port=1313 -b="www.myweb.com" --appendPort=false --buildDrafts --buildFuture --bind 0.0.0.0

I run my nginx proxy manager with this compose file (extract):

version: '3'
services:
  npm-app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: always
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    environment:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_DB_MYSQL_USER: myuser
      DB_MYSQL_PASSWORD: "mypassword"
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - /home/user/dockers/web/mywebsite/public:/site

And in the nginx proxy manager GUI interface, for the subdomain, under the Custom Nginx Configuration I put:

location / {
  root /site/;
}

As shown here.

But, the problem is that running hugo as exposed, the ‘/public’ folder is still empty.

If I try to execute hugo via docker exec -u 33 -it hugo-hugo-1 hugo, I get permission erros:

Start building sites … 
hugo v0.121.1-00b46fed8e47f7bb0a85d7cfc2d9f1356379b740+extended linux/amd64 BuildDate=2023-12-08T08:47:45Z

Total in 19 ms
Error: error building site: failed to acquire a build lock: open /src/.hugo_build.lock: permission denied

I tried with root, just to test:

docker exec -u root -it hugo-hugo-1 /bin/sh

And indeed I could execute hugo command from within and the contents of /public were generated and I could access to the site via https on my subdomain www.myweb.com.

But the files under /public belong to the root user, which I don’t think is intented, right?

So how show I correctly do it?

I have not looked into your specific case, but I recall running into a similar permissions problem with a Hugo/Docker image.

This is what I ended up with… the user and group id’s solved the problem.

docker run --rm -v .:/project -v $HOME/.cache/hugo_cache:/cache -u $(id -u):$(id -g) --network host veriphor/hugo hugo

I use the image above (sometimes) for local testing/development, and it’s the image I use for GitLab Pages sites. It’s big because it contains all optional dependencies (asciidoctor, pandoc, rst, etc.).

Dockerfile
ARG VERSION_DART_SASS=1.79.4
ARG VERSION_GO=1.23.1
ARG VERSION_HUGO=0.135.0
ARG VERSION_NODE=20.x
ARG VERSION_PAGEFIND=1.1.1
ARG VERSION_UBUNTU=24.04

# Base image
FROM ubuntu:${VERSION_UBUNTU}

# Default shell
SHELL ["/bin/bash", "-c"]

# Working directory
WORKDIR /project

# Intall utilities
RUN apt update && \
    apt upgrade -y && \
    apt install -y --no-install-recommends ruby brotli curl git lsb-release pandoc python3-docutils shared-mime-info && \
    apt clean

# Install gems
RUN gem install asciidoctor

# Configure Git
RUN git config --system --add safe.directory '*' && \
    git config --system --add core.quotepath false

# Intall Pagefind (regular and extended)
ARG VERSION_PAGEFIND
RUN curl -LJO https://github.com/CloudCannon/pagefind/releases/download/v${VERSION_PAGEFIND}/pagefind-v${VERSION_PAGEFIND}-x86_64-unknown-linux-musl.tar.gz && \
    tar -C /usr/local/bin -xzf pagefind-v${VERSION_PAGEFIND}-x86_64-unknown-linux-musl.tar.gz && \
    rm pagefind-v${VERSION_PAGEFIND}-x86_64-unknown-linux-musl.tar.gz && \
    curl -LJO https://github.com/CloudCannon/pagefind/releases/download/v${VERSION_PAGEFIND}/pagefind_extended-v${VERSION_PAGEFIND}-x86_64-unknown-linux-musl.tar.gz && \
    tar -C /usr/local/bin -xzf pagefind_extended-v${VERSION_PAGEFIND}-x86_64-unknown-linux-musl.tar.gz && \
    rm pagefind_extended-v${VERSION_PAGEFIND}-x86_64-unknown-linux-musl.tar.gz

# Intall Node.js
ARG VERSION_NODE
RUN apt install -y ca-certificates curl gnupg && \
    mkdir -p /etc/apt/keyrings && \
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${VERSION_NODE} nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
    apt update && \
    apt install nodejs -y && \
    mkdir /.npm && \
    chmod 777 /.npm

# Intall Go
ARG VERSION_GO
RUN curl -LJO https://go.dev/dl/go${VERSION_GO}.linux-amd64.tar.gz && \
    tar -C /usr/local -xzf go${VERSION_GO}.linux-amd64.tar.gz && \
    rm go${VERSION_GO}.linux-amd64.tar.gz
ENV PATH="$PATH:/usr/local/go/bin"

# Intall Dart Sass
ARG VERSION_DART_SASS
RUN curl -LJO https://github.com/sass/dart-sass/releases/download/${VERSION_DART_SASS}/dart-sass-${VERSION_DART_SASS}-linux-x64.tar.gz && \
    tar -xf dart-sass-${VERSION_DART_SASS}-linux-x64.tar.gz && \
    cp -r dart-sass/ /usr/local/bin && \
    rm -rf dart-sass*
ENV PATH="$PATH:/usr/local/bin/dart-sass"

# Install Hugo
ARG VERSION_HUGO
RUN curl -LJO https://github.com/gohugoio/hugo/releases/download/v${VERSION_HUGO}/hugo_extended_${VERSION_HUGO}_linux-amd64.deb && \
    apt install -y ./hugo_extended_${VERSION_HUGO}_linux-amd64.deb && \
    rm hugo_extended_${VERSION_HUGO}_linux-amd64.deb
ENV HUGO_CACHEDIR="/cache"
ENV HUGO_SECURITY_EXEC_ALLOW="^(asciidoctor|babel|git|go|npx|pandoc|postcss|rst2html|sass|tailwindcss)$"

# Copy scripts
COPY --chmod=755 info.sh /usr/local/bin/info

# Labels
LABEL com.veriphor.hugo.documentation="https://gohugo.io/documentation/"
LABEL com.veriphor.hugo.license="Apache-2.0"
LABEL com.veriphor.hugo.source="https://github.com/gohugoio/hugo"
LABEL com.veriphor.hugo.version="${VERSION_HUGO}"
LABEL org.opencontainers.image.authors="Joe Mooring <joe.mooring@veriphor.com>"
LABEL org.opencontainers.image.description="Hugo is a static site generator written in Go, optimized for speed and designed for flexibility."
LABEL org.opencontainers.image.documentation="https://hub.docker.com/r/veriphor/hugo"
LABEL org.opencontainers.image.title="Hugo"
LABEL org.opencontainers.image.url="https://hub.docker.com/r/veriphor/hugo"
LABEL org.opencontainers.image.vendor="Veriphor LLC"
LABEL org.opencontainers.image.version="${VERSION_HUGO}"

Thanks for the answer, @jmooring!

It gives me:

Error: command error: unknown shorthand flag: 'u' in -u

And I don’t see any reference in man hugo for -u or the word “user” :thinking:.

The -u user:group is a Docker CLI flag, not a Hugo flag.

:sweat_smile::sweat_smile::sweat_smile::person_facepalming::person_facepalming::person_facepalming:

Now run:

docker run -p 1313:1313 -u $(id -u):$(id -g)\
  -v ${PWD}:/src \
  hugomods/hugo:latest \
  hugo server --port=1313 -b="www.myweb.com" --appendPort=false --buildDrafts --buildFuture --bind 0.0.0.0

But still an empty public folder. And if I get in:

docker exec -u 33 -it crazy_moore /bin/sh

And execute it like:

/src $ hugo
Start building sites … 
hugo v0.121.1-00b46fed8e47f7bb0a85d7cfc2d9f1356379b740+extended linux/amd64 BuildDate=2023-12-08T08:47:45Z

Total in 18 ms
Error: error building site: failed to acquire a build lock: open /src/.hugo_build.lock: permission denied

Still the same error, as you can see.


EDIT:

Okey, since I was executing docker with an specific user/group id, I checked which one actually my user has, which is 1000, and tried with the same one:

docker exec -u 1000 -it crazy_moore /bin/sh

And now public folder content is generated and site can be viewed! Thank you so much!

1 Like

I understand. The command works as expected with the image I referenced when running locally, but your setup is obviously quite different. I was hopeful that the user:group would help resolve your problem, but I guess not.

I’m glad it’s working for you.

1 Like

I was just editing my response!

I just needed to get into that container with the same user id!

id -u
1000
docker exec -u 1000 -it crazy_moore /bin/sh
/src $ hugo
Start building sites … 
hugo v0.121.1-00b46fed8e47f7bb0a85d7cfc2d9f1356379b740+extended linux/amd64 BuildDate=2023-12-08T08:47:45Z


                   | EN  
-------------------+-----
  Pages            |  7  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     |  0  
  Processed images |  0  
  Aliases          |  1  
  Sitemaps         |  1  
  Cleaned          |  0  

Total in 37 ms

Thanks again!

1 Like

But still an empty public folder.

That’s because hugo server doesn’t output the files to public folder by default (default is memory).
You can either replace hugo server with hugo, or append --renderToDisk flag to hugo server.
I’d recommend using the former if you don’t need the Hugo server.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.