Documentationยถ

Descriptionยถ

This role publishes the Infinito.Nexus documentation for the latest commit and for every release tag. It builds the repositoryโ€™s Markdown, reStructuredText and role READMEs into an HTML site with Sphinx and the Awesome Sphinx Theme. There is no database.

Overviewยถ

One python:<version>-slim container runs the service in files/python/infinito_docs/:

  1. It keeps a git mirror of services.docs.source_repository in the docs_sites volume and fetches it every services.docs.fetch_interval seconds. The deployed snapshot, built from the image, starts before the first fetch; every other version waits for that fetch.

  2. latest is the last commit of the default branch. It is built at start and rebuilt whenever a fetch finds a new commit; the previous build stays online until the new one replaces it.

  3. A release tag (vX.Y.Z) is built the first time someone opens it. The browser shows a progress bar and reloads once the build is done. Tags never change, so a tag is built again only after the cap in point 6 dropped it.

  4. Up to two builds run at once, each with several parallel Sphinx processes. Both numbers follow the containerโ€™s memory limit: every build reserves services.docs.build.sphinx_overhead_mb plus services.docs.build.sphinx_process_mb per Sphinx process, a second build starts only when two processes fit for each, and a build never runs more processes than half the hostโ€™s CPUs. A free slot claims a translated site only once its version is current, so a version and its first language run in sequence.

  5. Every replica serves from the shared docs_sites volume. The replica holding builder.lock in that volume fetches and builds; the queue (queue/), the build states (states/) and the open stamps (opened/) are files beside the sites, so a new lock holder resumes the queue when the builder dies. Cross-node locking relies on NFSv4, the default of svc-storage-nfs-client.

  6. Only the three release tags opened last stay on disk, besides latest and deployed. Every request below /<tag>/ stamps opened/<tag>. After each build the builder drops every further tag, the one opened longest ago first, with its site, its translated sites, its prepared trees (prepared/), its build states and its queued languages. A tag stays while one of its builds runs or the tag itself is queued. The count is KEPT_TAGS in build_queue.py.

Path

Content

/

Redirect to /latest/

/<version>/...

The built site, or its build progress

/versions/

Every version with its build status and progress

/api/versions

The same as JSON

Every page carries a version switcher in its sidebar. Switching keeps the current page and falls back to the start page of a version that lacks it.

Architectureยถ

ARCHITECTURE.md draws Documentation from its own metadata: the containers it runs under compose, what changes under swarm, how each volume is backed, and every role it depends on or is depended upon by.

Section

Drawn from

Compose

meta/services.yml

Swarm

meta/services.yml replicas and placement

Volumes

meta/volumes.yml against the NFS decision chain

Dependencies

meta/services.yml and meta/main.yml of every role

Featuresยถ

  • Every release: The latest commit is the default, each release tag is selectable and built on demand.

  • Generated reference: API pages via sphinx-apidoc, one page per role from its meta/main.yml and README, and an index of every YAML file.

  • Folder navigation: The sidebar mirrors the repository tree and highlights the current page and heading.

Quick Setupยถ

Developmentยถ

Clone, set up the workstation, and deploy Documentation onto the local stack:

git clone https://github.com/infinito-nexus/core.git
cd core
make onboard
make compose-deploy mode=reinstall apps=web-app-docs full_cycle=false

Productionยถ

Run the published image to provision the inventory and deploy Documentation to a managed server over SSH. The image logs in as root, so the server must accept root over a public key, and the two key variables are the two halves of one key pair: the private half authenticates the deploy, and the public half is what the deploy keeps authorized for root and installs for the administrator account. Naming a public half that does not belong to the private one locks the running deploy out at its next reconnect.

APP=web-app-docs
HOST="<your-server>"
DOMAIN="<your-domain>"
TLS_MODE=self_signed
SSH_PUBLIC_KEY="<your-ssh-public-key>"
SSH_PRIVATE_KEY="<your-ssh-private-key-file>"
WORKDIR="$HOME/.infinito.nexus"

mkdir -p "$WORKDIR/inventories"
docker run --rm \
  -v "$WORKDIR/inventories:/etc/infinito.nexus/inventories" \
  -v "$SSH_PRIVATE_KEY:/run/secrets/deploy_key:ro" \
  -e APP="$APP" -e HOST="$HOST" -e DOMAIN="$DOMAIN" -e TLS_MODE="$TLS_MODE" -e SSH_PUBLIC_KEY="$SSH_PUBLIC_KEY" \
  ghcr.io/infinito-nexus/core/debian:latest bash -c '
    INVENTORY=/etc/infinito.nexus/inventories/production
    infinito administration inventory provision "$INVENTORY" \
      --inventory-file "$INVENTORY/devices.yml" \
      --host "$HOST" \
      --include "$APP" \
      --vars "{\"TLS_MODE\": \"$TLS_MODE\", \"DOMAIN_PRIMARY\": \"$DOMAIN\", \"SYS_SVC_SSHD_PERMIT_ROOT_LOGIN\": \"prohibit-password\", \"users\": {\"root\": {\"authorized_keys\": [\"$SSH_PUBLIC_KEY\"]}, \"administrator\": {\"authorized_keys\": [\"$SSH_PUBLIC_KEY\"]}}}" &&
    infinito administration deploy dedicated "$INVENTORY/devices.yml" \
      --password-file "$INVENTORY/.password" \
      -u root --private-key /run/secrets/deploy_key \
      --diff -vv'

The inventory under $WORKDIR is written by the container as root, including the vault password at inventories/production/.password. Run sudo chown -R "$USER" "$WORKDIR" afterwards to read it.

Configurationยถ

Override these keys of services.docs in the inventory:

Key

Purpose

source_repository

Repository to document, e.g. a fork

fetch_interval

Seconds between two fetches of new commits and tags

build.sphinx_process_mb

Memory reserved per parallel Sphinx process

build.sphinx_overhead_mb

Memory reserved per build besides its Sphinx processes; each parallel build also costs another scratch tree on disk

mem_limit

Container memory limit; raise it to run more Sphinx processes and builds at once

cpus

Container CPU cap; also takes a percentage of the host, e.g. 50%, see sys-svc-container

applications:
  web-app-docs:
    services:
      docs:
        source_repository: https://git.example.com/your-org/core.git
        cpus: "4"
        mem_limit: 16g

A dropped tag is built again the next time someone opens it. To rebuild a version that is still on disk, delete sites/<version> inside the docs_sites volume; its next visit builds it again from prepared/<version>.*, so delete that tree too to regenerate its sources.

Further Resourcesยถ

Creditsยถ

Marko Pjevac, Kevin Veen-Birkenbach

Part of the Infinito.Nexus Project and maintained by Kevin Veen-Birkenbach. Licensed under the Infinito.Nexus Community License (Non-Commercial).

This role deploys no third-party application, so the licence above is the only one that applies.

Persona contract opt-outsยถ

The role publishes a public documentation site. meta/services.yml pins sso.enabled and sso.shared to false, and the role ships no meta/users.yml and no account provisioning; templates/env.j2 only configures the build service. tasks/main.yml only wires the container and proxy stack and stages the Sphinx tooling into the build context. There is no account and no auth chain for the biber or administrator persona, so templates/playwright.env.j2 declares PERSONA_BIBER_BLOCKED=true and PERSONA_ADMINISTRATOR_BLOCKED=true. The guest persona and the baseline reachability and CSP assertions run unconditionally.