From f7eee4fc3eca979df2d145dbb0877d682e142e85 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 8 Sep 2026 08:35:49 +0000 Subject: [PATCH] refactor: stand up vantage-docs as its own repository docsite/ becomes the repository root; the whole repository is the site. The image is vantage/vantage-docs:latest, was mrhid6/vantage/docsite. The workflow passes no build args, as the monorepo's did not: DOCS_URL, DOCS_BASE_URL, APP_URL and HQ_URL have correct defaults in the Dockerfile, and passing an unset repo variable would blank one rather than leave it alone. --- .gitea/workflows/deploy.yml | 45 +++++++++++++++++++ .gitignore | 2 +- CLAUDE.md | 90 +++++++++++++++++++++++++++++++++++++ deploy/docker-compose.yml | 24 ++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 CLAUDE.md create mode 100644 deploy/docker-compose.yml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..5aa8a9c --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,45 @@ +name: Deploy + +on: + push: + branches: + - main + # DOCS_URL, DOCS_BASE_URL and APP_URL are repo variables, and editing one + # pushes no commit — so nothing would rebuild on its own. This is the + # escape hatch for that, and DOCS_BASE_URL in particular is baked into + # every asset path in the build. + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-docker + container: docker:dind + steps: + - name: Setup + run: apk add --update nodejs npm git + + - name: Checkout + uses: actions/checkout@v4 + + - name: Log in to registry + run: | + echo "${{ secrets.RELEASE_TOKEN }}" | \ + docker login ${{ vars.DOCKER_HOST }} \ + -u "${{ secrets.REGISTRY_USER }}" --password-stdin + + # One image, one directory — the whole repository is the docs site, + # so there is nothing to detect a change in. It rebuilds on every + # push, which is what a docs site wants anyway. + # + # No build args are passed, deliberately: DOCS_URL, DOCS_BASE_URL, + # APP_URL and HQ_URL all have correct defaults in the Dockerfile, + # and passing an unset repo variable would blank one rather than + # leave it alone. DOCS_BASE_URL in particular must match the proxy + # location that routes here and the directory the runtime stage + # serves from; when those three disagree the HTML loads and every + # asset 404s. Change it in the Dockerfile, not here. + - name: Build and push image + run: | + IMAGE="${{ vars.DOCKER_HOST }}/vantage/vantage-docs:latest" + docker build -t "$IMAGE" . + docker push "$IMAGE" diff --git a/.gitignore b/.gitignore index 93fcdeb..2b3a467 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ node_modules build .docusaurus -.cache-loader +.env diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..f1ffbfa --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,90 @@ +# Vantage documentation (`vantage-docs`) + +The user-facing documentation, served at **vantage.hostxtra.co.uk/docs**. +Docusaurus 3 in docs-only mode (`routeBasePath: "/"`, no blog), one version +tracking `main`, search indexed at build time by +`@easyops-cn/docusaurus-search-local` so nothing external is keyed or called. + +Extracted from the `vantage` monorepo with its history, where it was +`docsite/`. The whole repository is the site — there is no subdirectory. + +It documents the **product**, not the codebase: each repository's own CLAUDE.md +remains the contributor's map, and the two are allowed to differ in altitude but +not in fact. Five sections — Getting started, Vantage, Vantage HQ, Reference, +Operations — with `sidebars.ts` authored by hand so ordering is a decision +rather than a filename accident. + +## A path, not a subdomain + +`*.vantage.hostxtra.co.uk` is the per-tenant instance namespace, and the control +plane's `APP_ROOT_LABEL` resolves an instance from the label before `vantage` — +so a `docs.` label would be read as a tenant slug. Hence `/docs` on the +marketing host instead. + +**Three things must agree, and when they do not the HTML loads while every +asset 404s:** + +1. `DOCS_BASE_URL` (default `/docs/` in the Dockerfile) +2. the proxy location that routes here — which must also sort **above** the + catch-all forwarding to `site:3003`, or Next answers the 404 first +3. the directory the runtime stage serves from, + `/usr/share/nginx/html/docs` + +The proxy forwards the **full** path; it does not strip `/docs`. That is the +whole reason the third item exists. + +Unlike the three Next apps this builds to static files, so its runtime stage is +`nginx:alpine-slim` rather than Node, and it listens on **80**, not 3000. + +## Design tokens + +`src/css/custom.css` holds `vantage-site`'s `web/app/globals.css` token blocks +**copied verbatim** — same names, same values. This is the one place the tokens +are not consumed through Tailwind: everything below the token block maps +Docusaurus's `--ifm-*` variables onto them. Docusaurus already stamps +`data-theme` on ``, which is the selector the dark block keys on, so the +built-in toggle needed no wiring. + +The rule holds all the same: **no rule in that file outside the token blocks may +carry a hex.** The one concession is `static/img/favicon.svg`, which must, for +the same reason the email layout must — a browser tab cannot read a token. + +**Nothing enforces the match across the four front ends, and they are now in +four repositories.** A token change here follows one in `vantage-site`; there is +no way to make them one commit. + +## Deployment + +A fragment, composed on top of the control plane's own file: + +```bash +docker compose \ + -f vantage/deploy/docker/docker-compose.yml \ + -f vantage-site/deploy/docker-compose.yml \ + -f vantage-docs/deploy/docker-compose.yml \ + -f vantage-admin/deploy/docker-compose.yml \ + up -d +``` + +Not part of a self-hosted install. + +## CI/CD + +`.gitea/workflows/deploy.yml`, on every push to `main` plus `workflow_dispatch`. +One image, `vantage/vantage-docs:latest`, from the repository root — the whole +repository is the site, so there is nothing to detect a change in and it +rebuilds on every push. + +**No build args are passed, deliberately.** `DOCS_URL`, `DOCS_BASE_URL`, +`APP_URL` and `HQ_URL` all have correct defaults in the Dockerfile, and passing +an unset repo variable would blank one rather than leave it alone — which for +`DOCS_BASE_URL` means every asset path in the build. Change them in the +Dockerfile. The monorepo's workflow passed none either; this preserves that. + +| Name | Type | Value | +| --------------- | ------ | ----------------------------------------------------------- | +| `RELEASE_TOKEN` | Secret | Gitea API token, `write:package`. No module fetch here, so it needs no org read access | +| `REGISTRY_USER` | Secret | Gitea username. Must own `RELEASE_TOKEN` | +| `DOCKER_HOST` | Variable | registry host used for image tags | + +Despite the name the workflow **does not deploy**; it only builds and pushes. diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..3a504b4 --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,24 @@ +# The user documentation, served at vantage.hostxtra.co.uk/docs. +# +# A fragment, composed on top of the vantage repository's own file — see the +# vantage-site fragment for the full command. +# +# A path on the marketing host, not a subdomain: *.vantage.hostxtra.co.uk is +# the per-tenant instance namespace, and the control plane's APP_ROOT_LABEL +# would read a `docs.` label as a tenant slug. +# +# The proxy location that routes here must sort ABOVE the catch-all forwarding +# to site:3003, or Next answers the 404. It forwards the FULL path — it does +# not strip /docs — so the proxy location, DOCS_BASE_URL and the directory the +# image serves from (/usr/share/nginx/html/docs) must all agree. When they do +# not, the HTML loads and every asset 404s. +# +# Unlike the Next apps this is a static build behind nginx, so it listens on 80 +# rather than 3000. +services: + docsite: + image: gitea.hostxtra.co.uk/vantage/vantage-docs:latest + restart: unless-stopped + ports: + - 3005:80 +networks: {}