refactor: stand up vantage-docs as its own repository
Deploy / deploy (push) Successful in 2m15s

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.
This commit is contained in:
2026-09-08 08:35:49 +00:00
parent cca6453b86
commit f7eee4fc3e
4 changed files with 160 additions and 1 deletions
+45
View File
@@ -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"
+1 -1
View File
@@ -1,4 +1,4 @@
node_modules
build
.docusaurus
.cache-loader
.env
+90
View File
@@ -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 `<html>`, 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.
+24
View File
@@ -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: {}