Skip to content

Infrastructure setup

VELA deploys along a single spectrum — from a laptop, to a managed cloud cluster, to a fully air-gapped sovereign install — from one codebase. Tenancy is a configuration, not a fork.

Deployment options at a glance

Target Artifact Stores Network
Local dev .venv + make serve in-memory offline
Dev backends docker-compose.yml Neo4j + Qdrant local
Production (single host) docker-compose.prod.yml Neo4j + Qdrant + Postgres local
Cloud / on-prem cluster charts/vela (Helm) in-cluster or managed as configured
One-command on-prem deploy/onprem (k3d) in-cluster Neo4j/Qdrant/Postgres local cluster
Air-gapped Helm + private registry mirror in-cluster no egress

Local development

Terminal window
uv venv --python 3.12 && uv pip install -e ".[dev]"
make serve # API with CORS open to the Vite dev origins, auth off
make seed # POST the reference scenarios so the console has real cases
cd apps/console && npm run dev

The in-memory VELA-REF-1 path is the offline default — no Docker required.

Real stores with Docker Compose

docker compose up -d brings up Neo4j + Qdrant only (there is no Yamcs service — VELA is read-only and ground-segment). Then:

Terminal window
uv pip install -e ".[backends]"
VELA_STORE_BACKEND=neo4j VELA_DOC_SEARCH_BACKEND=qdrant VELA_NEO4J_PASSWORD=veladev \
python -m vela.kg.ingest

docker-compose.prod.yml additionally wires Postgres for durable investigation persistence and a durable checkpointer (the in-process MemorySaver does not survive a restart).

Kubernetes (Helm)

The charts/vela chart deploys the API + ingest for cloud and air-gap clusters. Key values (see charts/vela/values.yaml and charts/vela/README.md):

  • image + imagePullSecrets (mirror every image into a private registry for air-gap)
  • config.mode (airgap / cloud), config.authMode (apikey / oidc / saml)
  • store backends (Neo4j / Qdrant / Postgres) and their connection settings
  • podSecurityContext runs as a non-root uid (10001)
Terminal window
helm lint charts/vela
helm template charts/vela # render manifests

One-command on-prem (k3d)

deploy/onprem/up.sh stands up a local k3d cluster with in-cluster Neo4j/Qdrant/Postgres (stores.yaml), installs the Helm chart, runs KG ingest, and verifies an end-to-end cited investigation on the in-cluster stores. down.sh tears it down. This path is verified on Apple-Silicon k3d.

Air-gapped / sovereign install

The air-gap posture is the default for sovereign and defence customers:

  1. Mirror every image (including any operator) into a private registry — Harbor/Nexus is the load-bearing dependency — or use a container-tarball save/load path.
  2. Install the Helm chart with config.mode=airgap. VELA hard-fails any live telemetry source and any non-deterministic reasoning in airgap, and performs no external egress.
  3. Identity via Keycloak (self-hostable OIDC/SAML) and secrets via Vault (Shamir unseal) both sit behind existing seams.

Decide the one-way doors up front

The tenancy model, per-tenant encryption keys, and audit design are hard to change later. Prefer per-tenant keys / residency as the isolation boundary; do not make row-level security the only boundary. See ADR 0015.

Configuration & modes

vela/config.py::load_settings resolves mode as explicit arg > VELA_MODE > airgap, merges config/<mode>.yaml, then applies env overrides (VELA_STORE_BACKEND, VELA_DOC_SEARCH_BACKEND, VELA_NEO4J_*, VELA_QDRANT_*, telemetry-source paths). Secrets (VELA_NEO4J_PASSWORD, API keys) are read from env at connect time only. The API reads VELA_API_HOST|PORT, VELA_AUTH_ENABLED, VELA_API_KEYS, VELA_AUTH_MODE, VELA_SCIM_TOKEN.

This documentation site

These docs are built with MkDocs Material and deployed to GitHub Pages by .github/workflows/docs.yml on every push to main. Build locally with:

Terminal window
uv pip install mkdocs-material
mkdocs serve # live preview at http://127.0.0.1:8000
mkdocs build # static site into ./site