Cross-cutting

Self-host

Every product runs on-prem via a single Docker bundle. License JWTs gate which /v1/<product>/* namespaces are reachable, so dava-norm-selfhost and dava-suite-selfhost are the same image with a different license.

Quickstart

From the repo root (or the customer-facing release tarball):

bashcd infra/selfhost
cp dava.config.yaml.example dava.config.yaml
$EDITOR dava.config.yaml      # license JWT, S3 / MinIO, SMTP, secrets

./dava-init.sh                # renders .env from the YAML
docker compose -f docker-compose.suite.yaml up -d
docker compose -f docker-compose.suite.yaml exec api \
  alembic -c packages/core/alembic.ini upgrade head

# First-run wizard (you'll see this once):
open https://<your-host>/setup

License JWT

Self-host requires a JWT issued by AVA Research carrying:

  • customer_id — your account id.
  • products — subset of norm / dedup / connect / agent / trust.
  • exp — Unix epoch when the license expires.
  • mode online (phones home daily, 7-day offline tolerance) or airgap (signed offline, no phone-home).
  • seats — informational seat cap.

Set DAVA_LICENSE_JWT and DAVA_LICENSE_SECRET in your .env. On lifespan startup the API verifies the signature; uncovered product routes return 403 license_missing_<product>.

Because it's the same image, you can buy a Norm-only license, run the suite compose, and only /v1/norm/* will respond. Adding Connect later just means a new JWT — no new image to deploy.

Operations

Backups. Bind-mount the dava_pg and dava_minio volumes into your snapshot pipeline. The bundled stack writes everything there. A read-only restore drill runbook ships at docs/runbooks/restore-drill.md with an automated script at scripts/restore-drill.sh.

Observability. Bring your own Prometheus, or opt into the bundled stack with the --profile observability compose flag. That adds Prometheus + Grafana + Postgres/Redis exporters with a default DAVA dashboard (Grafana on :3001).

Upgrades. Bump DAVA_VERSION in .env, docker compose pull, then up -d. Migrations run via the API service's release command on next start; rollback is DAVA_VERSION=<previous> && up -d.