Renders the repository's Markdown (which stays where it is) into a
member-readable static site with Material for MkDocs: co-op brand colours
and logo, self-hosted OFL Figtree, offline search, no external hosts.
- publishing/build.sh stage .site-src, render .site-build (mkdocs --strict)
- publishing/deploy.sh write the build into the Surfer app container
- publishing/webhook-receiver.py + .service Gitea push hook on main
triggers pull -> build -> deploy (agent host, no new
Cloudron app)
Publishing the documentation site
The Markdown in this repository is the single source of truth. This directory is the publishing layer that turns it into a member-readable static site and puts it on the co-op's Surfer app. Documents are never edited here — a change to a document is a normal commit or pull request against the Markdown at the repository root.
What is built
| File | Purpose |
|---|---|
../mkdocs.yml |
Site configuration (MkDocs + Material for MkDocs) |
brand.css |
Co-op palette + self-hosted Figtree webfont (SIL OFL 1.1) |
fonts/ |
Figtree woff2 files and the OFL licence text |
logo.svg |
Co-op logo (shared with the website repo) |
build.sh |
Stage the Markdown into .site-src/, render to .site-build/ |
deploy.sh |
Push the build into the Surfer app container |
webhook-receiver.py |
Gitea webhook → pull → build → deploy (agent host) |
webhook-receiver.service |
systemd unit for the receiver |
requirements.txt |
Pinned Python build toolchain |
Nothing external is loaded by the site: no CDN, no third-party font service. Fonts are served from this repository's own output.
Build
publishing/build.sh # creates .venv-docs on first run
Output lands in .site-build/ (gitignored). mkdocs build --strict is what
CI-style runs should use, so broken links fail the build.
Deploy
CLOUDRON_TOKEN=... publishing/deploy.sh
Writes the build into the Surfer app (Cloudron app inference.coop) at:
/app/data/public-docs/— served at https://docs.inference.coop//app/data/public/docs/— served at https://inference.coop/docs/
Both are written so the site stays reachable either way; the hostname is the canonical one.
Automatic rebuilds (push to main)
A push to main on co-op/docs fires a Gitea webhook (repo settings →
webhooks) to the receiver on the agent host, which pulls, rebuilds and
redeploys. On the agent host:
sudo cp publishing/webhook-receiver.service /etc/systemd/system/docs-deploy-webhook.service
sudo systemctl daemon-reload && sudo systemctl enable --now docs-deploy-webhook
tail -f /home/ubuntu/docs-deploy.log # what the receiver is doing
The receiver authenticates webhooks with an HMAC-SHA256 shared secret
(DEPLOY_WEBHOOK_SECRET in the agent host's env file) and only accepts pushes
to main of co-op/docs from the Cloudron box. Woodpecker CI (Cloudron
catalog) could do the same job inside Cloudron, at the cost of running another
app; the receiver was chosen because it adds no new Cloudron app.
Each deploy writes meta.json into the site with the commit it was built
from, so a deploy can be verified from the served site itself:
https://docs.inference.coop/meta.json