synnet-devhub (this docs hub)
Synced read-only from
/home/synnet/synnet-devhub/README.md. Edit at the source, not here.
SYNNET DevHub
Section titled “SYNNET DevHub”Internal-only developer documentation hub. One place to browse, per module, its
README, CLAUDE.md, ROADMAP, and docs/ — synced read-only from every
SYNNET repo. Served on the LAN with Caddy tls internal. Containerized and
migratable: move the container, re-point the mounts, update internal DNS.
- Built with Astro + Starlight (static, fast, built-in Pagefind search).
- Manifest-driven: register every module in
modules.jsononly. - Content is synced read-only from source repos — edit at the source, never here.
- Auto-rebuilds when any watched source changes.
How it works
Section titled “How it works”bin/sync.mjs reads modules.json and assembles a Starlight content tree under
src/content/docs/modules/<category>/<id>/, pulling each module’s README.md
(overview), CLAUDE.md, ROADMAP, docs/, and optional adr/ / runbooks/.
Markdown without frontmatter gets a title injected (Starlight requires one) plus
a source-attribution note. The sidebar (src/generated/sidebar.json) is generated
from the manifest and consumed by astro.config.mjs.
In production, a builder container syncs + builds the static site into a shared
volume and watches sources for changes; caddy serves that volume over the LAN.
Quick start — local
Section titled “Quick start — local”pnpm installpnpm dev # sync + Starlight dev server (live reload; no search index)# or:pnpm build && pnpm preview # full static build incl. Pagefind searchPoint modules.json source paths at real repos on your machine (or run with a
test manifest: MODULES_FILE=modules.dev.json pnpm build).
Quick start — internal server (production)
Section titled “Quick start — internal server (production)”- Edit
infra/compose.yamlvolume mounts so each repo is mounted read-only at the/repos/...path used inmodules.json. - Point internal DNS so
synvirt.mxresolves to this host on the LAN (split horizon). DevHub serves the/devpath; never expose it publicly. - Bring it up and trust the internal CA on your machines/browsers:
cd infradocker compose up -d --build# trust Caddy's internal root CA (so https://synvirt.mx/dev has no warning):docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt /tmp/synnet-devhub-ca.crtsudo cp /tmp/synnet-devhub-ca.crt /usr/local/share/ca-certificates/synnet-devhub-ca.crtsudo update-ca-certificates(Or use the Taskfile.yml targets: task up, task trust-ca.)
modules.json
Section titled “modules.json”{ "categories": [ { "id": "synvirt", "label": "SynVirt — Product" } ], "modules": [ { "id": "synvirt-core", // url + folder id (unique) "title": "synvirt (core daemon)", "category": "synvirt", // must match a category id "source": "/repos/synvirt", // container path (mounted read-only) "readme": "README.md", // optional, default README.md -> overview "claude": "CLAUDE.md", // optional -> claude page "roadmap": "docs-internal/roadmap.md", // optional -> roadmap page "docsDir": "docs", // optional -> docs/ subtree "adrDir": "docs-internal/adr", // optional "runbooksDir": "runbooks" // optional } ]}Add a module
Section titled “Add a module”- Mount its repo read-only in
infra/compose.yaml(e.g./srv/foo:/repos/foo:ro). - Add an entry to
modules.jsonpointingsourceat/repos/foo. - The
builderrebuilds automatically (or runpnpm buildlocally).
- Internal only. No public ACME, no Cloudflare. Caddy
tls internalper SYNNET internal-services policy. - Migratable. State is just: the container image,
modules.json, and the mounted repos. To move hosts: copy the project, re-point mounts, update DNS. - Path vs subdomain. This ships under
synvirt.mx/dev(Astrobase: /dev). Internal DNS forsynvirt.mxmust point at this host on the LAN; the Caddyfile serves/dev/*from the built site and can optionally proxy the rest to the public platform ingress. Mind split-horizon routing against the public site. - English for all UI, code, commits, logs and docs.