Files
ThothII/docs/operations/public-docs-publication.md
T
Codex b1c510a097
Publish documentation / publish (push) Successful in 36s
fix(docs): preserve theme assets in deny-by-default publication
2026-09-16 09:36:30 +02:00

4.7 KiB

Publishing the public manual

This is an internal operator runbook. Publishing documentation must not recreate the ThothII application, Gitea, proxy, DWH or other documentation containers.

Three separate states

  1. main contains reviewed source and the public allowlist in mkdocs.yml.
  2. Gitea Actions builds and validates the generated pages branch. A successful Actions run alone does not update the live site.
  3. The live manual is served by the dedicated thothii-docs nginx container on the host reached through the existing trusted SSH alias contabo. Its Compose project/service are thothii-docs/docs.

This procedure is manual. No timer, webhook, credential or automatic deployment has been added. Use the operator's existing SSH authorization and known host key; never disable host verification to make a publication work.

Build and stage

From a clean ThothII main checkout already pushed to Gitea:

git status --short
git rev-parse HEAD
./scripts/build-docs.sh
bash scripts/auth-docs-smoke.sh
bash scripts/verify-dwh-auth-docs.sh
bash scripts/test-auth-docs-smoke.sh
bash scripts/test-verify-dwh-auth-docs.sh

The strict build also verifies the public boundary: exactly 20 navigation pages, five approved source assets, no internal pages/assets, and matching search entries. The locked Windmill theme requires a separate exact allowlist of 25 static assets; MkDocs applies exclude_docs to those files too. Never replace the list with broad directory exceptions. Sources under docs/ may not shadow theme asset paths. The verifier follows stylesheet/script/image references and CSS font references from generated pages and fails when a local dependency is absent.

Choose a unique release identifier consisting of UTC timestamp and source SHA. Record the current symlink and container identity before proceeding:

ssh -oBatchMode=yes -oStrictHostKeyChecking=yes contabo \
  'readlink /srv/thothii-docs/current; docker inspect --format "{{.Id}} {{.State.Health.Status}}" thothii-docs'

On the server, create /srv/thothii-docs/releases/RELEASE/site only if RELEASE does not exist. Copy the current nginx.conf unchanged into the new release. Transfer the local built site/ into that new empty directory with rsync over the same verified SSH connection. Do not use --delete against current, and do not edit routing, TLS, network or authentication configuration.

Activate only this site

Replace RELEASE below with the validated identifier, not a user-supplied path. Keep the previously recorded release for rollback.

cd /srv/thothii-docs
test -f releases/RELEASE/site/index.html
test -f releases/RELEASE/nginx.conf
docker exec thothii-docs nginx -t
ln -s releases/RELEASE current.next
mv -Tf current.next current
docker compose --project-name thothii-docs -f docker-compose.yml \
  up -d --no-deps --force-recreate docs

Check that current.next does not already exist before creating it; stop if it does, because another publication or recovery may be in progress. Changing the symlink alone is insufficient: an existing Docker bind mount still resolves to the old release. The service recreation above remounts the new directory. It may briefly interrupt this manual only.

Verify, record, or roll back

  • Wait for docker inspect to report this container healthy; verify mounted paths and nginx configuration. Stop after a bounded timeout (for example 60 s).
  • Without login/cookies, require HTTP 200 for home, search and both install/standalone-manual-it/ and install/standalone-manual-en/.
  • Compare live home and search/search_index.json checksums to the build. Search must contain only the 20 approved pages, never plans, reports or architecture.
  • Check the actual stylesheet and JavaScript URLs in both installation pages: HTTP 200, CSS served as text/css, JavaScript with a valid script content type, and fonts available. In a browser confirm the stylesheets load and the layout is styled. HTML 200 alone is not enough to accept a publication.
  • Require HTTP 404 for retired/internal paths, including architecture/overview/, plans/2026-09-08-memory-management/, and operations/compose-reference/.
  • Record source SHA, release ID, previous release and checks in the cleanup/release record. Do not call the publication complete solely because pages was pushed.

If health or public verification fails, point current back to the recorded previous release using a fresh temporary symlink and the same atomic rename, then recreate only service docs with the same Compose command. Verify health and old site availability. Do not delete either release during recovery. Historical releases are retained; pruning them requires a separate retention decision.