Building this site

The first real entry, about the site itself.

labpage is a static site — Hugo turning Markdown into plain HTML, no client-side JavaScript, no database. It’s packaged as a small Docker image (Hugo builds the site in one stage, nginx serves it in the next) and deployed to the homelab’s k3s cluster through the same GitOps pipeline everything else here runs on: merge to main, and a pipeline builds the image, pushes it, and updates the deployment.

Two real bugs showed up while wiring that up. First, the initial Docker build failed silently on hugo: not found — the fuller-featured Hugo binary needs glibc, and the minimal Linux base image in the build stage only has musl. Fix was simple once diagnosed: this site doesn’t use any of the Sass features that binary exists for, so the plain, statically linked build works fine and needs nothing extra. Second, the release pipeline could push the built image but couldn’t update the deployment definition — it turned out cloning that repository needed the same credentials as pushing to it, not just the push step, which is an easy thing to miss the first time.

The more interesting decision was how much of the release process should be hands-off. Publishing a post here always goes through review before it merges — sanitizing a public write-up is a judgment call, not something worth automating away. But once a post is already reviewed and merged, updating the running deployment to match it is pure bookkeeping. Gating that behind a second, separate approval didn’t add any real safety — it just created a second place for an already-approved change to sit unmerged if nobody happened to notice it. So that part now happens automatically; the actual editorial gate stays exactly where the judgment call actually is.