Skip to main content

Quickstart

Run the DVARA AI governance platform locally with a single docker compose up, create your first tenant and API key in the DVARA Flightdeck, and make a governed, OpenAI-compatible chat completion — end to end in under five minutes. Policy, PII scanning, budget enforcement, and the audit trail kick in on the very first request.

This page uses the ready-made quick-start stack from the dvara-examples repository. For every other deployment topology (multi-provider, Ollama, full MCP), see Docker Compose Setup.

DVARA requires a license key

The DVARA LLM Gateway and the DVARA Flightdeck both need a DVARA--prefixed license envelope to start (the DVARA MCP Proxy in the full stack reuses the same envelope — pick one key for all three).

Get a self-hosted trial license (pick one):

  1. Book a demo — fill in the Book a demo form (also reachable from the navbar). Share your name, work email, company, team size, and a use case — explicitly mention you need a trial license for a self-hosted install. The team emails a 30-day trial envelope back, typically the same business day.
  2. Email support — if the web form is blocked (corporate proxy, SSO, air-gapped), email support@dvarahq.com with the same details. A human replies with a 30-day trial envelope the same business day.

Don't need a self-hosted install? Start a free trial on SaaS instead.

Prerequisites

  • Docker 20.10 or later with Compose v2 (docker compose, not the legacy docker-compose).
  • A DVARA license key (trial or production).
  • At least one provider API key. The quick-start stack is wired for OpenAI only (OPENAI_API_KEY=sk-...). To use more providers out of the box, jump to the multi-provider stack. To run with no external provider at all, see the Ollama stack for local models.
  • Free TCP ports 8080 (gateway data plane), 8090 (DVARA Flightdeck), and 5432 (PostgreSQL). If any of these are taken, edit the ports: mappings in docker-compose.yml before starting the stack.

Step 1: Clone the examples and pick a stack

git clone https://github.com/dvarahq/dvara-examples.git
cd dvara-examples/docker-compose/quick-start

The quick-start/ stack runs three services:

  • PostgreSQL (port 5432) — config, audit, and tenant store for the governance platform. Requires PostgreSQL 14 or later; the example stack pins postgres:16-alpine.
  • DVARA LLM Gateway (port 8080) — the governed data plane that serves OpenAI-compatible API calls.
  • DVARA Flightdeck (port 8090) — the web UI and Automation API for managing policies, tenants, budgets, and the audit trail.

Step 2: Configure your keys

cp .env.example .env

Open .env in your editor. The committed .env.example lists every variable the quick-start stack expects:

# .env — quick-start stack
DVARA_LICENSE_KEY=DVARA-...<your-license-envelope>

# rc24+ required secrets — generate each: `openssl rand -base64 32`
DVARA_ENCRYPTION_MASTER_PASSWORD=<openssl-rand-output>
DVARA_ACTUATOR_API_KEY=<openssl-rand-output>
DVARA_ACTUATOR_METRICS_API_KEY=<different-openssl-rand-output>
DVARA_AUDIT_HMAC_SECRET=<openssl-rand-output>

OPENAI_API_KEY=sk-<your-openai-key>
DB_PASSWORD=dvara
  • DVARA_LICENSE_KEY — your DVARA license envelope from the trial email.
  • DVARA_ENCRYPTION_MASTER_PASSWORD — Encrypts the provider API keys that DVARA stores. Save this value somewhere safe — losing it permanently locks you out of every stored credential.
  • DVARA_ACTUATOR_API_KEY — Bearer required by the Flightdeck License/Status page and any other authenticated actuator path (except /actuator/prometheus).
  • DVARA_ACTUATOR_METRICS_API_KEY — separate Bearer required only by /actuator/prometheus. Must differ from DVARA_ACTUATOR_API_KEY (principle of least privilege).
  • DVARA_AUDIT_HMAC_SECRET — HMAC-SHA256 key for the tamper-evident audit chain. Production profiles refuse to start on the default value.
  • OPENAI_API_KEY — your OpenAI API key. For other providers, see the multi-provider/ stack.
  • DB_PASSWORD — PostgreSQL password. Leave as dvara for local evaluation; change it for any other environment.

To reject keyless data-plane requests with HTTP 401, also uncomment DVARA_LLM_GATEWAY_REQUIRE_API_KEY=true in .env. The default false lets unauthenticated requests through (anonymous, no tenant attribution) — convenient for the first smoke test in Step 4, but unsafe for any deployment past evaluation.

Two layers of keys
  • Provider key (sk-...) — used by the gateway to call OpenAI. Never given to client code.
  • DVARA key (gw_...) — used by your application to call the gateway. Created in Step 5.

Step 3: Start the stack

docker compose up -d
Already ran this stack before? Pull first.

The quick-start uses pull_policy: missing, so docker compose up reuses any cached image instead of fetching the newest published one. To refresh to the latest release, pull first:

docker compose pull # fetch the newest :latest images from GHCR
docker compose up -d # restart with the refreshed images

First-time evaluators with no local cache skip this — the initial up pulls the most recent image automatically.

Apple Silicon / arm64 hosts

DVARA images are published linux/amd64 only. Docker Desktop on Apple Silicon pulls and runs them under Rosetta automatically — you may see a one-line The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) warning at boot, but everything works and you can ignore it. The data-plane performance overhead is negligible for evaluation workloads.

If you're running docker run directly (not docker compose), add --platform linux/amd64 to silence the warning. On non-Desktop Docker (e.g. plain Docker Engine on a Linux/arm64 host), --platform linux/amd64 is required, not optional.

The three containers (postgres, dvara-gateway, dvara-flightdeck) come up in order — PostgreSQL first (healthcheck-gated), then the gateway, then the DVARA Flightdeck. Total time on a warm Docker cache is ~30 seconds; the first run is slower because images pull from GitHub Container Registry.

Check everything is running:

docker compose ps

Expected output — all three services should report running with healthy status:

NAME STATUS PORTS
quick-start-dvara-gateway-1 Up 45 seconds (healthy) 0.0.0.0:8080->8080/tcp
quick-start-dvara-flightdeck-1 Up 30 seconds (healthy) 0.0.0.0:8090->8090/tcp
quick-start-postgres-1 Up 50 seconds (healthy) 0.0.0.0:5432->5432/tcp

Check the gateway is alive:

curl -s http://localhost:8080/actuator/health | python3 -m json.tool

For the rich gateway status (license, region, version, providers, routes, warnings), call /actuator/gateway-status with the operator's DVARA_ACTUATOR_API_KEY Bearer — or just open the DVARA Flightdeck's License page, which renders the same data through the browser session.

# The key was generated for you in .env during Step 1. Source it once:
source .env

curl -s http://localhost:8080/actuator/gateway-status \
-H "Authorization: Bearer $DVARA_ACTUATOR_API_KEY" \
| python3 -m json.tool

List the models the gateway currently exposes — this hits OpenAI live and returns each model with its capability flags:

curl -s http://localhost:8080/v1/models | python3 -m json.tool

For interactive prompt testing, use the Playground in the DVARA Flightdeck at http://localhost:8090/playground (requires admin login). The playground can be disabled in production with DVARA_FLIGHTDECK_PLAYGROUND_ENABLED=false.

Step 4: Make your first request

With the gateway running, make an OpenAI-compatible chat completion directly against port 8080:

curl -s -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "What is the capital of France?"}
]
}' | python3 -m json.tool

You should see a standard OpenAI chat completion response:

{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "gpt-4o",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The capital of France is Paris."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 14,
"completion_tokens": 8,
"total_tokens": 22
}
}

If the request fails

The two most common first-run errors, and what each means:

{
"error": {
"message": "No provider configured for model: gpt-4o. Set OPENAI_API_KEY to register the provider.",
"type": "invalid_request_error",
"code": "no_provider",
"trace_id": "84423bed556c4a71a9d73758e8881d08"
}
}

The gateway does not see an OpenAI provider registered. The error message tells you exactly which environment variable to set. Stop the stack (docker compose down), re-check the value in .env, and bring it back up — environment variables are read at container start, so editing .env while the stack is running does nothing.

{
"error": {
"message": "OpenAI API error 401 (invalid API key - check your provider credentials)",
"type": "provider_error",
"code": "provider_error",
"trace_id": "a6783439db1f46a6bfed511a0011e955"
}
}

The key is configured but OpenAI rejected it. Verify the key works outside DVARA with curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY".

Step 5: Create a tenant and your first API key

The request above went through the gateway without an API key. This bypasses all tenant-scoped enforcement (rate limits, budgets, policies, PII detection, cost attribution) and should only be used for initial smoke testing. Real applications authenticate with a DVARA API key that identifies a tenant — that is how all governance features work.

Production deployments

Set DVARA_LLM_GATEWAY_REQUIRE_API_KEY=true to reject keyless requests with 401. Without this, requests bypass all tenant-scoped governance.

Open the DVARA Flightdeck at http://localhost:8090. On first visit you will be redirected to /setup to create the initial owner account (email + password).

First-run /setup form for creating the initial owner accountFirst-run /setup form for creating the initial owner account
Figure 1. First-run /setup form for the initial owner

Once you are signed in:

  1. TenantsCreate Tenant. Give it a name like My Team and leave the defaults. Submit.
Create Tenant form — name, status, region defaultsCreate Tenant form — name, status, region defaults
Figure 2. Create Tenant form — name + status + region; defaults are fine for the quickstart
Tenants list after creating a tenantTenants list after creating a tenant
Figure 3. Tenants list — your new tenant appears here
  1. Click into the new tenant → API KeysCreate Key. Give it a name like quickstart-key and submit.
Create-key modal in the tenant API keys pageCreate-key modal in the tenant API keys page
Figure 4. Create-key modal — name and scope the new key
  1. Copy the generated gw_... key from the confirmation screen — it is shown exactly once and never stored in plaintext. If you close the modal without copying, create another key.
Plaintext key reveal — the gw_... value is shown exactly oncePlaintext key reveal — the gw_... value is shown exactly once
Figure 5. Plaintext reveal — copy now; the key is never stored in plaintext

Now repeat the chat completion call with the DVARA key attached:

curl -s -X POST http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer gw_<your-tenant-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "Hello from my first tenant"}
]
}' | python3 -m json.tool

Go back to the DVARA Flightdeck and open Dashboard — you should see the request appear in the live metrics panel within a few seconds. Open Audit and you will see a GATEWAY_RESPONSE audit event tagged with your tenant ID and API key fingerprint. Open Token Usage to see the tokens and cost broken down per tenant.

Flightdeck Dashboard live metrics after the first governed requestFlightdeck Dashboard live metrics after the first governed request
Figure 5. Dashboard — your first request appears in the live metrics within seconds

Using the OpenAI SDK

DVARA is fully OpenAI-compatible — point any OpenAI SDK at http://localhost:8080/v1 and pass the DVARA key as api_key. The gateway handles everything else (tenant routing, rate limiting, audit, cost tracking, guardrails). To call Anthropic, Gemini, Bedrock, or any other DVARA-supported provider through the same OpenAI SDK, only the model field changes.

Copy-paste examples for every supported SDK and framework live in SDK & Framework Integrations:

  • Python — OpenAI Python, Anthropic SDK via DVARA, AWS Bedrock, Google GenAI, LiteLLM, LangChain
  • JavaScript / TypeScript — OpenAI JavaScript, Anthropic JS, Vercel AI SDK
  • Java — OpenAI Java SDK, Spring AI, LangChain4j

Stop the stack

docker compose down # stop containers, keep the postgres volume
docker compose down -v # stop and also delete the postgres volume

Use down while you are iterating — it preserves your tenants, API keys, audit trail, and configuration across restarts. Use down -v only when you want to reset the environment completely.

Troubleshooting

STARTUP FAILED: PostgreSQL is required

If the gateway crashes on startup with this banner, the SPRING_DATASOURCE_* environment variables are missing. DVARA requires PostgreSQL — there is no in-memory fallback.

========================================
STARTUP FAILED: PostgreSQL is required
========================================
spring.datasource.url is not configured.
DVARA requires PostgreSQL — there is no
in-memory fallback.
========================================

Every stack in dvara-examples already wires PostgreSQL correctly. If you see this error, make sure you ran docker compose up -d from inside docker-compose/quick-start/ (or one of the other stack directories) — not from a custom file that stripped out the database service.

STARTUP FAILED: license key missing

If either container crashes with a license banner, DVARA_LICENSE_KEY is either unset, set to an empty string, or pasted with a line break in the middle. Both the gateway and the DVARA Flightdeck validate the token at startup, so both must see the same value.

Fix:

  1. Re-copy the license token from the trial email — one continuous string, no whitespace.
  2. Put it in .env as DVARA_LICENSE_KEY=DVARA-... (the license is a DVARA--prefixed Ed25519-signed envelope, not a JWT).
  3. docker compose down && docker compose up -d.

Environment values are read at container start; editing .env while the stack is running has no effect until you restart.

Next steps

  • Docker Compose Setup — all four stacks (quick-start, multi-provider, ollama, full) and how to enable OIDC, SAML, or built-in auth
  • Provider Setup — configure OpenAI, Anthropic, Gemini, Bedrock, Azure OpenAI, Mistral, Cohere, Groq, Qwen, DeepSeek, Moonshot, ChatGLM, Grok, and Ollama in detail
  • Configuration Reference — every environment variable the gateway and DVARA Flightdeck understand
  • API — interactive OpenAPI reference for every /v1/* endpoint, with a configurable Try it panel