Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Build and host the docs

These docs are Markdown in docs/site/src/, built into a static site with mdBook (a Rust build tool, MPL-2.0; it is not a dependency of any PolarSystems program). Anyone can build and host a copy, for example on an internal network.

What is generated

The PolarBot Reference pages are generated from the source code by a test in crates/polarbot and checked in. The test fails when a page and the code differ, so after changing commands, config keys, migrations, credentials, the unit file or the log levels, regenerate them and commit the result:

POLAR_UPDATE_DOCS=1 cargo test -p polarbot docs_reference

Everything else is written by hand. The Changelog is the repository’s CHANGELOG.md, included when the site is built.

Build

cargo install mdbook --locked
deploy/build-docs.sh

cargo install puts mdbook into ~/.cargo/bin. The script (it also needs python3):

  1. runs the reference test, so a stale reference is never published;
  2. builds the site into docs/site/book/ (not committed) and fails on any mdBook warning;
  3. moves mdBook’s inline scripts into files under inline-js/, so the site works under a strict Content-Security-Policy without 'unsafe-inline';
  4. fails if any page would load something from another host, or carries an inline style the CSP does not allow.

The site loads nothing from other hosts: no web fonts, no CDN, no analytics. MathJax and the Rust playground of mdBook are switched off in docs/site/book.toml. Search runs in the browser from a local index.

To preview while writing: mdbook serve docs/site and open http://localhost:3000.

Host it with nginx

The steps mirror the OAuth callback site, with deploy/nginx-docs.polarsystems.net.bootstrap.conf and deploy/nginx-docs.polarsystems.net.conf. Replace docs.example.org with your host name (Fedora: use /etc/nginx/conf.d/docs.example.org.conf as SITE and skip the ln lines).

SITE=/etc/nginx/sites-available/docs.example.org
sudo mkdir -p /var/www/letsencrypt /var/www/docs.example.org
sed 's/docs\.polarsystems\.net/docs.example.org/g' deploy/nginx-docs.polarsystems.net.bootstrap.conf | sudo tee "$SITE" >/dev/null
sudo ln -sf "$SITE" /etc/nginx/sites-enabled/docs.example.org
sudo nginx -t && sudo systemctl reload nginx
sudo certbot certonly --webroot -w /var/www/letsencrypt -d docs.example.org --deploy-hook "systemctl reload nginx"
sed 's/docs\.polarsystems\.net/docs.example.org/g' deploy/nginx-docs.polarsystems.net.conf | sudo tee "$SITE" >/dev/null
sudo nginx -t && sudo systemctl reload nginx

Then publish a build (again after every change):

sudo rsync -a --delete docs/site/book/ /var/www/docs.example.org/

or from a workstation, rsync -a --delete docs/site/book/ <server>:/var/www/docs.example.org/ with a user that may write there.

The site:

  • serves only GET and HEAD, never hidden files, and keeps no access log;
  • sends HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy: no-referrer and a Content-Security-Policy that allows scripts, styles, fonts and images from the site itself only (plus the three inline styles mdBook uses, by hash);
  • lets browsers cache scripts, styles and fonts for a week (their file names change with their content) and revalidate pages on every visit.

If you change mdBook’s theme or version and build-docs.sh reports an inline style that is not allowed, add its hash to the CSP (printf '%s' '<style value>' | openssl dgst -sha256 -binary | base64) in the nginx site and in the script’s ALLOWED_STYLES.