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):
- runs the reference test, so a stale reference is never published;
- builds the site into
docs/site/book/(not committed) and fails on any mdBook warning; - moves mdBook’s inline scripts into files under
inline-js/, so the site works under a strict Content-Security-Policy without'unsafe-inline'; - 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
GETandHEAD, never hidden files, and keeps no access log; - sends HSTS,
X-Content-Type-Options,X-Frame-Options,Referrer-Policy: no-referrerand 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.