- Hugo static site at root: config, content (home/about/resume/blog + 5 projects), data/resume.yaml, custom layouts (gpu background, resume renderer, projects list), dark theme with canvas behind content - gpu-bg/: extracted WebGPU/WebGL2 spiral engine as a Vite sub-package; slim bootstrap drops router/overlay/text renderer; fixed uniforms (scene0/dim0); self-contained engine.js - archive/: retired Vite SPA preserved (router, overlay, data, engine/text orphaned) - 3-stage Dockerfile (node -> hugo extended/dart-sass -> nginx), static nginx config - DEPLOYMENT.md handover + README rewrite; pre-hugo rollback tag
4.3 KiB
Deployment Handover
How the migrated Hugo site is served, and how to adjust the server-side deploy workflow (Gitea Actions + webhook) for the new two-stage build.
Serving topology (unchanged)
The site is served as before. The host's system nginx (Certbot-managed TLS at djosen.one) proxies location / → 127.0.0.1:8080, where the Docker web container listens. Nothing changed in the system nginx (nginx/system-default.conf / nginx/reverse.conf) or the Certbot/DNS setup during this migration.
What changed is what's inside the container: instead of a Vite SPA (a single index.html plus JavaScript), the container now serves a Hugo static site — public/ with one real .html page per path.
What changed in the build
The build is now two steps:
- Engine —
gpu-bg/Vite/Typescript build → a static JS bundle (gpu-bg/dist/). - Site —
hugo --minify→public/.
The Dockerfile runs both in stages (node → hugo → nginx).
Key details for the server build:
- Hugo image: the
sitestage useshugomods/hugo:debian-dart-sass-go-0.165.0— an extended Hugo build including dart-sass. This is required because hugo-coder compiles the theme's SCSS via Hugo Pipes (toCSS), and Hugo 0.129+ dropped libsass in favor of dart-sass. This replaced the deprecatedklakegg/hugoimage. - Theme submodule: hugo-coder lives as a git submodule at
themes/hugo-coder. - Static serving only: the container nginx no longer does SPA fallback (
try_files ... /index.html). It serves plain static files — each page is a real.html, and a 404 for a missing path is legitimate and intentional.
Mandatory server-side change (the #1 gotcha)
Your clone/checkout must initialize submodules before building. The themes/hugo-coder submodule must be pulled in before docker build; otherwise hugo fails with theme not found and the build breaks.
-
Gitea Actions
deploy.yml: make the checkout recursive. Withactions/checkout, set:- uses: actions/checkout@v3 with: submodules: recursive -
Plain webhook / shell: use a recursive clone, or run the update before building:
git clone --recursive ... # or, on an existing clone: git pull git submodule update --init --recursive
Nothing else changes server-side: registry credentials, the SSH/webhook target, and the docker compose up -d deploy command are all the same. The image is slightly larger to build (node and Hugo-extended layers are discarded; the final nginx stage stays small).
Testing
Local (before pushing)
git submodule update --init --recursive
cd gpu-bg && npm install && npm run build && cd ..
hugo # builds public/
docker compose build # 3-stage build
docker compose up -d # maps 127.0.0.1:8080:8080
Smoke test (after up -d)
curl -sf http://127.0.0.1:8080/ | grep -q 'id="gpu"' && echo "canvas OK"
curl -sf http://127.0.0.1:8080/gpu/engine.js -o /dev/null && echo "engine bundle OK"
curl -sf http://127.0.0.1:8080/about/ -o /dev/null && echo "about OK"
curl -sf http://127.0.0.1:8080/projects/ -o /dev/null && echo "projects OK"
curl -sf http://127.0.0.1:8080/resume/ -o /dev/null && echo "resume OK"
curl -sf http://127.0.0.1:8080/posts/ -o /dev/null && echo "posts OK"
curl -s http://127.0.0.1:8080/nonexistent -o /dev/null -w "%{http_code}\n" # expect 404
Browser check (manual — WebGPU is a real-GPU feature)
- Homepage: emerald spiral animates behind the dark glass panel; text readable.
- With WebGPU disabled, the WebGL2 fallback still animates.
- With no WebGL at all, the page still shows its content; the canvas simply doesn't render.
After deploy (remote)
curl -s https://djosen.one/health→ok(system nginx health endpoint, unchanged).- Verify
/,/about/,/projects/,/resume/,/posts/over HTTPS. - Confirm the spiral actually renders in a real browser — the one thing
curlcannot check.
Rollback
The previous site is preserved in the git tag pre-hugo and the archive/ folder. To roll back: git checkout pre-hugo and redeploy with the old single-stage Dockerfile (also recoverable from git history).
No system nginx or DNS changes were made in this migration, so rollback is purely a container-image swap.