Skip to content

Commit d64185a

Browse files
authored
Merge pull request #418 from VirtualFlyBrain/pin-builder-hugo-0.122
Pin the builder to Hugo 0.122.0, the last version that completes this build
2 parents 00ae61d + e9019ed commit d64185a

1 file changed

Lines changed: 65 additions & 27 deletions

File tree

‎Dockerfile‎

Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,74 @@
33
# docker build -t vfb-static-builder .
44
# docker run --rm -v "$PWD:/src" -v vfb_cache:/tmp vfb-static-builder
55
#
6-
# v0.164.0 is the newest stable Hugo (released 2026-07-06) and the site builds
7-
# clean on it: 186 pages, no WARN, no ERROR. Pinned rather than :latest so
8-
# rebuilding this image cannot silently change the site.
9-
#
10-
# The theme's declared minimum is 0.128.0 (`[pagination] pagerSize`). It does
11-
# also build on 0.122.0, which is what rcourt/docsy-builder:Feb2023 carries, but
12-
# that image has no rsync and warns about the declared minimum.
13-
#
14-
# Base is Alpine 3.22, so apk is correct. The upstream image already carries
15-
# git, Node, npm and Dart Sass. This site needs none of them — the theme ships
16-
# plain CSS concatenated by Hugo, so even the extended edition is optional — but
17-
# they come with the official image and are not worth stripping out.
18-
#
19-
# bash and rsync are for deploy.sh, which stages the build and syncs it into the
20-
# served directory rather than writing there directly. findutils replaces
21-
# busybox find so the page-count gate behaves predictably.
22-
FROM ghcr.io/gohugoio/hugo:v0.164.0
6+
# Pinned to Hugo 0.122.0 rather than the newest release. That is a deliberate
7+
# step backwards and the reason is measured, not suspected.
8+
#
9+
# The content tree is ~763k generated term pages, ~650k of them in a single
10+
# directory (content/en/blog/ontologies/vfb), reached over NFSv3 from a Synology
11+
# volume whose btrfs metadata sits on RAID5 spinning disks. Measured on that
12+
# volume: plain readdir runs at 5-29k entries/s, but readdir+stat runs at
13+
# 253/s — ~4ms per inode, a disk seek, nothing cached. NFSv3 uses READDIRPLUS,
14+
# so the server stats every entry it enumerates. Per-page filesystem cost is
15+
# therefore the dominant term in this build, far above template or render cost.
16+
#
17+
# Hugo's per-page filesystem cost rose at v0.123.0, which rewrote page assembly.
18+
# Counted with strace over an identical 25k-page corpus on local disk:
19+
#
20+
# 0.122.0 75,658 openat 76,997 newfstatat 3.06 stat/page
21+
# 0.128.0 100,788 openat 101,527 newfstatat 4.04 stat/page
22+
# 0.140.2 100,813 openat 101,485 newfstatat 4.03 stat/page
23+
# 0.164.0 100,844 openat 101,488 newfstatat 4.03 stat/page
24+
#
25+
# Flat from 0.128 onward, so this is one regression at 0.123, not a drift. At
26+
# 763k pages and 253 stat/s that extra stat per page is ~49 min on top of a
27+
# build already costing ~2.6h of pure metadata I/O.
28+
#
29+
# 0.122.0 is the last version known to complete this build: the live term pages
30+
# carry `generator: Hugo 0.122.0` and were written 2026-08-05 17:59. No 0.16x
31+
# build has ever finished — each ran 17h+ with one thread in uninterruptible
32+
# sleep on the vfb/ directory and not a single page written.
33+
#
34+
# This pin is a workaround. The fix is to stop holding 650k files in one
35+
# directory (shard vfbterms.py's output) and to pin the volume's btrfs metadata
36+
# to its SSD cache. When either lands, raise HUGO_VERSION — it is an ARG so that
37+
# is a one-line change.
38+
#
39+
# Debian rather than Alpine, and the tarball rather than ghcr.io/gohugoio/hugo:
40+
# that registry has no v0.122.0 tag (it begins around v0.140), and the extended
41+
# release binary is glibc-linked — `ldd` gives /lib64/ld-linux-x86-64.so.2 plus
42+
# libstdc++.so.6 — so musl with gcompat is not a safe host for it.
43+
#
44+
# Extended edition, matching the rcourt/docsy-builder:Feb2023 that produced the
45+
# last good site. The theme ships plain CSS and needs no Sass, so the standard
46+
# edition would also serve and is statically linked; keeping extended here
47+
# changes one variable at a time relative to the last build known to work.
48+
#
49+
# The theme declares min_version 0.128.0 for `[pagination] pagerSize`, so 0.122
50+
# emits one WARN and falls back to 10 items per page. Nothing on the site
51+
# paginates today, so that is latent rather than active.
52+
FROM debian:bookworm-slim
53+
54+
ARG HUGO_VERSION=0.122.0
55+
56+
# bash and find are already in the base image. rsync is for deploy.sh, which
57+
# stages the build and syncs it into the served directory rather than writing
58+
# there directly. libstdc++6 is what the extended Hugo binary links against.
59+
RUN apt-get update \
60+
&& apt-get install -y --no-install-recommends rsync ca-certificates libstdc++6 \
61+
&& rm -rf /var/lib/apt/lists/*
62+
63+
ADD https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz /tmp/hugo.tgz
64+
RUN tar xzf /tmp/hugo.tgz -C /usr/local/bin hugo \
65+
&& rm -f /tmp/hugo.tgz \
66+
&& hugo version
2367

24-
# Deliberately root, unlike the upstream image's hugo:hugo. The published tree
25-
# on the NFS volume is owned by root from the klakegg-era builds, so an
26-
# unprivileged rsync could not overwrite it.
68+
# Deliberately root. The published tree on the NFS volume is owned by root from
69+
# the klakegg-era builds, so an unprivileged rsync could not overwrite it.
2770
USER root
28-
RUN apk add --no-cache bash rsync findutils
2971

30-
# The upstream image sets HUGO_CACHEDIR=/cache and WORKDIR /project. Both are
31-
# wrong here and neither can be left to deploy.sh's defaults: the script uses
32-
# ${HUGO_CACHEDIR:-/tmp/hugo_cache}, which never fires while the image has the
33-
# variable set, so the cache would land in the container's writable layer
34-
# instead of the volume mounted at /tmp — discarded every run, and growing host
35-
# disk in between. Rancher mounts the workspace at /src and the cache at /tmp.
72+
# deploy.sh uses ${HUGO_CACHEDIR:-/tmp/hugo_cache}, so this must be set
73+
# explicitly: Rancher mounts the workspace at /src and the cache volume at /tmp.
3674
ENV HUGO_CACHEDIR=/tmp/hugo_cache
3775
WORKDIR /src
3876

0 commit comments

Comments
 (0)