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 installand 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 buildwritessite/, 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.yml — site_url |
the path this project publishes at |
mkdocs.yml + deploy-docs.sh — DOCS_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.yml — strict: 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.