Skip to content

Serving these docs

This site is built by MkDocs with the Material theme, from the Markdown under docs/.

Why MkDocs and not Docusaurus

Both are good. MkDocs suits this project for reasons that are specific rather than general:

  • No second toolchain. Longbox is Python with no build step — server-rendered Jinja2, vanilla JS, nothing compiled. MkDocs is pip install and belongs in a requirements file next to everything else. Docusaurus would bring Node, npm and React onto a host that has no other reason to have them.
  • The source stays readable where it already lives. These are plain Markdown files that render perfectly well in a text editor or on a repository page, with no MDX or JSX in them. A reader who never builds the site loses nothing.
  • The output is static files. mkdocs build writes site/, which any web server can serve. Nothing new runs, and nothing new can break.

Docusaurus earns its weight when you need versioned documentation, a blog, or React components embedded in the prose. If versioning is ever wanted here, mike adds it to MkDocs without changing anything else.

Building it

pip install -r requirements-docs.txt
mkdocs serve          # preview on http://127.0.0.1:8000, live-reloading
mkdocs build          # static HTML into site/

requirements-docs.txt is separate from requirements-dev.txt on purpose: the suites must keep running on a machine that has never built the documentation, the same way they run without jsonschema.

mkdocs.yml sets strict: true, so a link to a page that does not exist fails the build rather than printing a warning nobody reads. That is the same reasoning behind naming a missing test dependency out loud: a check that silently does nothing is worse than no check, because it looks like coverage.

site/ is build output and is gitignored.

Hold the upper bound on mkdocs

MkDocs 2.0 removes the plugin system, rewrites theming, and ships with no migration path from 1.x — Material prints a warning about it on every build. The mkdocs>=1.6,<2 pin is doing real work.

Publishing it

Longbox's documentation is one site among several on a shared documentation host, published into its own subdirectory:

./deploy-docs.sh

Which is mkdocs build --strict followed by an rsync into /srv/docs/longbox/.

site_url is !ENV [DOCS_SITE_URL, ...], and the script composes that from ~/.config/docs-host — one untracked line naming the real host. So the canonical URL and sitemap.xml name the deployment while the repository names nobody, which is the anonymisation rule applied to a field that would otherwise break it quietly. Build without that file and the placeholder is used, and the script says so on stderr.

--delete targets the project subdirectory, never the root

Every project publishes into one tree, so a wrong destination deletes the others:

# Deletes every other project's documentation, and the landing page.
rsync -a --delete site/ /srv/docs/

Both paths keep their trailing slash. Without one on the source, rsync copies the directory itself and you get /srv/docs/longbox/site/.

This is why the path lives in a script rather than in shell history.

Where the host itself is documented

Building the documentation host, adding a project to it, the Caddy configuration, the landing page and the shared writing conventions are not documented here — they belong to the host rather than to Longbox, and putting them in one project's documentation would mean rebuilding the host required cloning that project first.

They live in the docs-platform repository, published at /platform on the docs host. Start at its README.md.

What is shared, and therefore worth checking

Six things in this repository are coupled to that one, and none of them are enforced at build time — each fails quietly, with the site still building and the deploy still running:

Here Coupled to
requirements-docs.txt the platform's pins — one virtual environment serves every project, so a different major version cannot be installed beside the others
deploy-docs.sh the deploy target, which must name the project; a --delete against the root removes every other project's documentation
deploy-docs.sh the mkdocs guard, without which the failure is command not found
mkdocs.ymlsite_url the path this project publishes at
mkdocs.yml + deploy-docs.shDOCS_SITE_URL the real host, supplied at deploy time from ~/.config/docs-host; if the script stops setting it, every publish quietly carries the placeholder
mkdocs.ymlstrict: true the --strict the deploy runs with
a row on the platform's landing page, without which this site cannot be navigated to

Changing any of them here means changing, or at least checking, the other repository in the same pass:

python ../docs-platform/check-projects.py .

Named assertions, non-zero on failure, standard library only. It reads local files and prints what it cannot see — nothing local knows whether /srv/docs on the server matches any of this.

If you are reading this having cloned Longbox on its own, none of that is needed: mkdocs serve above is self-sufficient, and mkdocs build gives you a folder of static files that any web server — or a browser opening site/index.html — will show.

Writing for this site

Full conventions are in the platform repository (docs/conventions.md). The two that matter most here:

Anonymise by default. comics.example.com for the name, 192.168.1.10 for a LAN address, generic usernames. Nothing in these pages should identify a real deployment; a documentation site is the easiest place in a project for a real host name to leak, and deploy/proxy/ carried one for several releases before it was noticed.

Link between pages by relative path, including the .md extension — ../operations/migration.md. MkDocs rewrites these to the right URLs, and strict mode catches the ones that are wrong.