The agent host's cloud firewall only admits inbound SSH, so the registered Gitea webhook cannot reach the receiver. docs-deploy-poll.service polls Gitea every 60s over outbound HTTPS and deploys whenever main moves; the webhook stays wired for the moment a port is opened in the Infomaniak panel. Both serialise on the same deploy lock.
3.4 KiB
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 |
poll-watcher.sh |
Polls Gitea main every 60s; deploys on change (agent host) |
docs-deploy-poll.service |
systemd unit for the poller |
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)
Two mechanisms keep the site in step with main; both run on the agent host
and neither adds a Cloudron app.
Polling (running now). docs-deploy-poll.service polls Gitea every 60
seconds and deploys whenever main moves. A push appears on the site within
about a minute, with no human action. The Gitea webhook alone was not enough
because the agent host's cloud firewall only admits inbound SSH — a webhook
POST is silently dropped — while outbound access to Gitea works.
Webhook (wired, waiting on one port). A Gitea webhook is registered on
co-op/docs (push events, branch main) pointing at the receiver below. The
moment the Infomaniak panel allows inbound TCP to the agent host — port 8787
from the Cloudron box 179.237.86.116 is enough — start the receiver and pushes
deploy instantly instead of within a minute:
sudo systemctl enable --now docs-deploy-webhook
tail -f /home/ubuntu/docs-deploy.log # what both mechanisms are 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 agent-host mechanisms were chosen because they add 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