feat: documentation site
Docusaurus 3 docs-only site at docsite/, served statically by nginx under /docs on the marketing host. Covers getting started (self-hosted install through first server and first licence), the control plane, Vantage HQ, a reference section and operations. Wired into docker-compose.site.yml as docsite (3005:80) and into the image build workflow, rebuilding on its own directory only. Never added to the self-hosted compose file.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
---
|
||||
id: environment-variables
|
||||
title: Environment variables
|
||||
sidebar_label: Environment variables
|
||||
---
|
||||
|
||||
Everything the control plane reads from the environment, and what happens when
|
||||
it is absent.
|
||||
|
||||
## Server
|
||||
|
||||
| Name | Required | Default | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `GRPC_HOST` | **yes** | — | The `host:port` agents dial. Boot fails without it. There is deliberately no fallback to the web host: that would hand every agent a port that does not speak gRPC |
|
||||
| `MONGO_URI` | no | `mongodb://localhost:27017` | The database name is taken from the URI path, falling back to `vantage`. There is no separate `MONGO_DB` |
|
||||
| `REDIS_ADDR` | no | `localhost:6379` | Sessions only |
|
||||
| `KEY_ENCRYPTION_KEY` | yes in practice | — | 64 hex characters (32 bytes) for AES-256-GCM. Required for private keys, vault secrets, OIDC client secrets and console credentials |
|
||||
| `GITEA_HOST` | yes | `gitea.example.com` | Used to build the install scripts and agent download URLs. The default is a placeholder that will not resolve |
|
||||
| `GUACD_ADDR` | no | `guacd:4822` | The [browser console](../vantage/browser-console.md) daemon |
|
||||
| `APP_ROOT_LABEL` | no | `vantage` | The app root label for the host and session organisation guard |
|
||||
| `VANTAGE_WORKFLOW_LOG_DIR` | no | — | Where workflow run logs are written |
|
||||
| `VANTAGE_DEFAULT_STEPS_DIR` | no | baked into the image | Where the seeded step library is read from |
|
||||
| `VANTAGE_DEPLOYMENT` | no | self-hosted | Set to `cloud` on a cloud instance. Governs whether a licence may be pasted |
|
||||
| `VANTAGE_LICENSE` | no | — | A licence blob, used **only** when the instance has no stored one |
|
||||
| `FREE_INSTANCE_REAP_AFTER` | no | empty | How long past a Free licence's expiry before the instance and all its data are deleted |
|
||||
|
||||
:::danger `KEY_ENCRYPTION_KEY` has no recovery path
|
||||
It encrypts SSH private keys, vault secrets, OIDC client secrets and console
|
||||
credentials. Lose it and all of them are unreadable. Back it up separately from
|
||||
the database it protects.
|
||||
:::
|
||||
|
||||
:::warning `FREE_INSTANCE_REAP_AFTER` empty means disabled, and empty is the default
|
||||
That is the correct value for a self-hosted install, which must never reap. It
|
||||
is set only on the hosted deployment.
|
||||
:::
|
||||
|
||||
:::info A wrong `APP_ROOT_LABEL` fails quietly
|
||||
It does not error. It simply stops matching, and the host/session guard stops
|
||||
protecting anything.
|
||||
:::
|
||||
|
||||
### Not configurable
|
||||
|
||||
The HTTP port (`8080`) and the gRPC port (`9090`) are fixed in the server. The
|
||||
`HTTP_PORT` and `GRPC_PORT` entries in the shipped Compose file are inert —
|
||||
remap with Docker's port publishing instead.
|
||||
|
||||
## Agent
|
||||
|
||||
The agent reads no environment variables. Everything is in its
|
||||
[config file](./agent-config.md).
|
||||
|
||||
## Hosted-only services
|
||||
|
||||
These run only on the hosted deployment, from
|
||||
`deploy/docker-compose.site.yml`. A self-hosted install runs none of them.
|
||||
|
||||
### sitesvc — the public contact form
|
||||
|
||||
| Name | Required | Notes |
|
||||
| --- | --- | --- |
|
||||
| `MONGO_URI` | yes | Must point at the control plane's database. Refuses to start against a database that has not run the instances migration. The database name is read from the URI path; a URI without one is refused rather than defaulted |
|
||||
| `SMTP_HOST`, `SMTP_FROM` | yes | Without them the contact form answers `503` rather than silently dropping messages |
|
||||
| `SMTP_TO` | no | Defaults to `support@hostxtra.co.uk` |
|
||||
| `SMTP_PORT` | no | Defaults to `587`; `465` uses implicit TLS |
|
||||
| `SMTP_USERNAME`, `SMTP_PASSWORD` | no | Auth is skipped when the username is empty |
|
||||
| `SITE_ORIGIN` | yes in practice | Comma-separated allowed origins. Unset refuses every cross-origin browser request |
|
||||
| `TRUST_PROXY` | no | Only `true` behind a proxy that overwrites `X-Forwarded-For`, or clients spoof past the rate limiter |
|
||||
|
||||
### admin — the licensing authority
|
||||
|
||||
| Name | Required | Notes |
|
||||
| --- | --- | --- |
|
||||
| `ADMIN_MONGO_URI` | yes | Admin's own database |
|
||||
| `CONTROL_MONGO_URI` | yes | The control plane's database, for licence injection and user projection |
|
||||
| `LICENSE_SIGNING_KEY` | yes | **The only service that ever holds this.** Never add it to the server, and never add admin to the self-hosted Compose file |
|
||||
| `REDIS_ADDR`, `REDIS_USERNAME`, `REDIS_PASSWORD` | yes | Admin uses an external Redis; the base Compose file hardcodes `redis:6379` for the server, so these reach admin only |
|
||||
| `ADMIN_ORIGIN` | yes | Comma-separated browser origins that call admin. See the warning below |
|
||||
| `PADDLE_API_KEY` | yes | Boot-required |
|
||||
| `PADDLE_WEBHOOK_SECRET` | yes | Boot-required. An unverified webhook endpoint is one anyone can issue licences through |
|
||||
| `PADDLE_ENV` | yes | `sandbox` or `production`. Selects which catalogue price IDs are served, and must match the value baked into the portal build |
|
||||
| `SMTP_*` | yes in practice | Account, licence and billing email |
|
||||
| `PUBLIC_URL`, `APP_LOGIN_URL` | yes in practice | Used in links inside emails |
|
||||
| `FREE_INSTANCE_REAP_AFTER` | yes | Must match the control plane's value. Admin only uses it to name the date in warning emails; the control plane performs the delete |
|
||||
|
||||
:::warning A missing `ADMIN_ORIGIN` entry produces no error anywhere
|
||||
The CORS layer simply omits the allow-origin header and still answers the
|
||||
preflight with `204`. The browser blocks the request and **admin logs nothing at
|
||||
all**. The symptom is a preflight failure on an endpoint that works perfectly
|
||||
under `curl`.
|
||||
:::
|
||||
|
||||
## Build-time variables
|
||||
|
||||
These are baked into frontend images at build time, not read at runtime.
|
||||
Changing one requires rebuilding that image — and because editing a CI variable
|
||||
pushes no commit, nothing rebuilds on its own. See [CI/CD](../operations/ci-cd.md).
|
||||
|
||||
| Name | Baked into |
|
||||
| --- | --- |
|
||||
| `API_URL` | `web` |
|
||||
| `HQ_URL` | `web` |
|
||||
| `SITE_API_URL`, `SITE_CONTACT_EMAIL` | `site` |
|
||||
| `ADMIN_API_URL` | `adminsite` **and** `site` |
|
||||
| `ADMIN_ENV`, `PADDLE_CLIENT_TOKEN`, `PADDLE_ENV` | `adminsite` |
|
||||
| `DOCS_URL`, `DOCS_BASE_URL` | `docsite` |
|
||||
Reference in New Issue
Block a user