Skip to main content
Version: 1.7.0

Docker Compose Setup

All DVARA Docker Compose stacks live in the public dvara-examples repo. Each variant is a self-contained directory — cd in, set your .env, and run docker compose up -d. For the 5-minute first-run experience, see Quickstart.

All stacks include PostgreSQL. DVARA requires it — there is no in-memory fallback.

Pre-built images

ImageWhat it isAccess
ghcr.io/dvarahq/dvara-gateway:1.7.0Data plane (:8080) — serves /v1/*, /mcp/* and /a2a/*Public
ghcr.io/dvarahq/dvara-flightdeck:1.7.0Console + Portal (:8090)Public

Two images, both public. There is one artifact per app and the license decides what activates, not which image you pull — see Container images & license posture.

Do not pull these

dvara-llm-gateway (renamed to dvara-gateway), dvara-mcp-gateway and dvara-a2a-gateway (retired — all three planes now run in the gateway process, so ports 8070 and 8075 no longer exist), and the -ee variants (there is no separate Enterprise build). Some of these still resolve to old pre-release images.

Tags: latest (current release) or a version tag (e.g. 1.7.0).

:::note Editions The public dvara-gateway / dvara-flightdeck images are all you need — pull and run with no license. The MCP / A2A proxies (no Community tier) are private images that need a license and a registry credential (docker login ghcr.io). See Editions & container images for the pull flow. The Compose stacks below run the Community images out of the box. :::

Topologies

StackServicesUse for
quick-start/postgres + gateway-server + gateway-uiFastest path to a running gateway. OpenAI only.
multi-provider/postgres + gateway-server + gateway-uiOpenAI + Anthropic out of the box. Add more providers (Gemini, Mistral, Cohere, Groq, Azure, Bedrock, Ollama) by uncommenting env vars.
ollama/postgres + gateway-server + gateway-ui + ollamaLocal models, no external LLM calls.
with-email/postgres + gateway-server + gateway-uiThe same shape as quick-start/, with transactional email (log / resend / smtp) and the delivery durability layer surfaced for tuning.
There is no full/ stack any more

It ran the MCP and A2A planes as their own containers. Since 1.7.0 those planes run inside the gateway process, so full/ was the same three services as quick-start/ plus a licence key — a directory naming a topology that no longer exists.

To get what it gave you: run quick-start/ and set DVARA_LICENSE_KEY in .env. The /mcp and /a2a paths then activate on :8080. Leave it blank and everything else still runs.

Clone once, then switch between stacks by cd-ing into a different directory:

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

Quick-start stack

The fastest path to a running gateway — PostgreSQL + gateway-server + DVARA Flightdeck with OpenAI as the only provider. This is what Quickstart walks through.

cd quick-start
cp .env.example .env
# edit .env — every uncommented variable is required; the file's
# inline comments explain each one and how to generate the random
# secrets (openssl rand -base64 32)
docker compose up -d

Want more than one provider? Use multi-provider/ below.

:::info Two kinds of credentials DVARA uses two separate credential layers:

  • Provider keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.) — infrastructure secrets the gateway uses to call upstream LLM providers. Set as env vars, or manage them through the DVARA Flightdeck's BYOK credential store, or integrate with vault.
  • Workspace API keys (gw_...) — application credentials your SDK uses to authenticate with the gateway. Create them in the DVARA Flightdeck after setting up a workspace.

In production, provider keys are managed by your ops/security team; workspace API keys are managed by platform admins through the dashboard or by workspace admins via the self-service portal. :::

Multi-provider stack

Same topology as quick-start/ but with OpenAI + Anthropic wired up out of the box, plus commented-out slots for every other supported provider. Providers register automatically at startup whenever their API key env var is set and non-empty — so adding Gemini, Mistral, Cohere, Groq, Azure OpenAI, Bedrock, or Ollama is just a matter of uncommenting a line in docker-compose.yml and setting the matching value in .env.

cd multi-provider
cp .env.example .env
# set OPENAI_API_KEY and/or ANTHROPIC_API_KEY
docker compose up -d

curl -s http://localhost:8080/v1/models | jq '.data[].id'
"gpt-4o"
"gpt-4o-mini"
"o3-mini"
"claude-sonnet-4-5"
"claude-opus-4-5"
...

/v1/models queries each configured provider live and returns the union, so the list is however many models your keys reach — not a catalogue DVARA maintains. An empty data array means no provider registered: check that the key env vars actually reached the container with docker compose exec dvara-gateway env | grep API_KEY.

This call works keyless only because the example stack is keyless

The Compose files here default DVARA_LLM_GATEWAY_REQUIRE_API_KEY to false, which is why the curl above needs no Authorization header. .env.example tells you to set it true for anything real — and once you do, this same command returns 401 api_key_required until you pass a workspace key.

To enable additional providers, open docker-compose.yml and uncomment the env vars under dvara-gateway.environment:

dvara-gateway:
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
GEMINI_API_KEY: ${GEMINI_API_KEY:-}
MISTRAL_API_KEY: ${MISTRAL_API_KEY:-}
COHERE_API_KEY: ${COHERE_API_KEY:-}
GROQ_API_KEY: ${GROQ_API_KEY:-}
AZURE_OPENAI_API_KEY: ${AZURE_OPENAI_API_KEY:-}
AZURE_OPENAI_BASE_URL: ${AZURE_OPENAI_BASE_URL:-}

Then set the matching values in .env. For Azure OpenAI you must set both AZURE_OPENAI_API_KEY and AZURE_OPENAI_BASE_URL. See Providers for the complete list and per-provider setup.

Local models with Ollama

Run entirely local — no provider API keys, no outbound LLM calls. The Community-Edition gateway needs no license; supply DVARA_LICENSE_KEY only to unlock Enterprise features.

cd ollama
cp .env.example .env # fill in every uncommented variable per the inline comments
docker compose up -d

# Pull a model
docker compose exec ollama ollama pull llama3.2

# Use it
curl -s -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "ollama/llama3.2",
"messages": [{"role": "user", "content": "Hello!"}]
}' | jq .

The stack includes a GPU-passthrough block commented out at the top of docker-compose.yml — uncomment it if you have an NVIDIA GPU and the NVIDIA Container Toolkit installed.

All three planes, one container

There is no separate stack to run for MCP or A2A. Since 1.7.0 the gateway serves all three governed planes in one process on port 8080:

planepathwhat it governs
LLM/v1model traffic
MCP/mcpthe tools your agents call
A2A/a2athe other agents your agents call

The MCP and A2A planes activate when the gateway starts with a valid license — that is one of the two things a license gates. Nothing else changes: same container, same port, same health probe.

curl http://localhost:8080/actuator/health
Upgrading from 1.6.0 or earlier

Earlier releases ran two more containers, dvara-mcp-gateway on 8070 and dvara-a2a-gateway on 8075. Both images are retired. Remove those services from your compose file and repoint anything addressing :8070 or :8075 at the gateway on :8080 — the paths are unchanged, so only the host and port move.

See Agentic Governance for the MCP plane and A2A Governance Plane for the A2A plane.

First-run setup

Open the DVARA Flightdeck at http://localhost:8090 — you'll be redirected to /setup to create the initial owner account. Full walkthrough in Setup & Login. For self-service portal access (workspace admin / developer / viewer roles), see Workspace Portal.

:::tip Disable authentication for local development If you prefer to skip authentication entirely during local development, add this to the dvara-flightdeck service environment section of any stack:

dvara-flightdeck:
environment:
DVARA_FLIGHTDECK_SECURITY_ENABLED: "false"
# ... other env vars

Never use this in production. :::

What the platform secrets do

The .env.example in each stack carries five DVARA-specific secrets in addition to provider keys + DB_PASSWORD. The stacks already wire each one into the right service — .env.example lists what to set; the compose files reference them. The summary below is for understanding what each one is for, not for hand-editing your compose YAML.

Env varWhat it doesFailure mode if unset
DVARA_LICENSE_KEYSigned DVARA envelope validated at startupGateway refuses to boot with a "No license key configured" error
DVARA_ENCRYPTION_MASTER_PASSWORDAES-256-GCM key for ENCRYPTED-mode credentials stored per-workspace in PostgreSQL (the BYOK Credentials store in the Flightdeck)ENCRYPTED-mode credential persistence fails; REFERENCE-mode (vault pointer) still works
DVARA_ACTUATOR_API_KEYOperator Bearer for /actuator/gateway-status + every authenticated /actuator/* path EXCEPT prometheusLicense page in Flightdeck stays empty; every authenticated actuator probe 401s
DVARA_ACTUATOR_METRICS_API_KEYDistinct Bearer for /actuator/prometheus onlyPrometheus scrape 401s on every poll; dashboard's live-metrics card stays empty. Must differ from DVARA_ACTUATOR_API_KEY — principle of least privilege
DVARA_AUDIT_HMAC_SECRETHMAC-SHA256 key for the tamper-evident audit chainSince 1.7.0, unset is safe here — an install with a database generates a secret on first boot and persists it, shared by every process signing that chain. What a production-class profile still refuses is the public default-dev-secret-change-in-production placeholder. Set it explicitly to hold the key material yourself, and always set it — the same value on both halves — where a data-plane pod ships audit to Flightdeck

The probe paths (/actuator/health, /actuator/health/liveness, /actuator/health/readiness, /actuator/info) stay anonymous so container health checks don't need credentials.

BYOK: credentials via the DVARA Flightdeck

Provider credentials can be managed through the DVARA Flightdeck under Credentials instead of (or in addition to) env vars. Keys are encrypted with AES-256-GCM and stored per-workspace in PostgreSQL — recommended for multi-tenant setups where each workspace brings their own provider keys (BYOK). The stacks already wire DVARA_ENCRYPTION_MASTER_PASSWORD into the gateway service; setting a non-default value in .env is all that's required.

Authentication modes

By default, the DVARA Flightdeck uses built-in email/password authentication. For production, DVARA supports three modes:

ModeWhen to useConfig required
Built-in (default)Local dev, small teams, no existing IdPNone — works out of the box
OIDCExisting Keycloak, Okta, or Azure ADDVARA_FLIGHTDECK_SECURITY_OIDC_ISSUER_URI
SAML 2.0Enterprise SSO (ADFS, Okta SAML, Azure AD)DVARA_FLIGHTDECK_SECURITY_SAML_METADATA_URL

Example — enabling OIDC on the DVARA Flightdeck by adding env vars to the dvara-flightdeck service:

dvara-flightdeck:
environment:
DVARA_FLIGHTDECK_SECURITY_OIDC_ISSUER_URI: https://keycloak.example.com/realms/dvara
DVARA_FLIGHTDECK_SECURITY_OIDC_AUDIENCE: dvara-admin
DVARA_FLIGHTDECK_SECURITY_OIDC_ROLE_CLAIM: realm_access.roles
# ... other env vars

OIDC and SAML are mutually exclusive — configuring both causes a startup error. The full property reference for OIDC + SAML lives in Setup & Login and Configuration.

Viewing logs

docker compose logs -f # all services
docker compose logs -f dvara-gateway # single service

Logs use structured JSON format by default. Switch to plain-text with SPRING_PROFILES_ACTIVE=log-plain.

Health probes

The DVARA Flightdeck exposes standard health endpoints for Docker health checks:

curl http://localhost:8090/actuator/health/liveness # liveness
curl http://localhost:8090/actuator/health/readiness # readiness (includes gateway-server connectivity)

See the DVARA Flightdeck Guide for full documentation.

Stopping

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

Troubleshooting

Port already in use

Override the host port by adding a ports override in a docker-compose.override.yml alongside the stack, or edit the stack's docker-compose.yml directly:

ports:
- "9080:8080" # maps host 9080 → container 8080

Gateway starts but providers are not registered

Check that environment variables are being passed through:

docker compose exec dvara-gateway env | grep -i api_key

Keys must be non-empty for providers to register.

STARTUP FAILED: PostgreSQL is required

All stacks in dvara-examples include PostgreSQL. If you see this error, you're likely running a stripped-down custom compose file without the postgres service or without the SPRING_DATASOURCE_* env vars on the gateway. Use one of the examples as a starting point.

Health check keeps failing

docker compose logs dvara-gateway | head -50

The gateway needs ~20-30 seconds to start (database migrations run on first boot). If it consistently fails, check for port conflicts and that your license key is valid.

Cannot log in to the DVARA Flightdeck

First-time users must create the initial owner account at http://localhost:8090/setup. If you've set up an account and forgotten the password, use Forgot password? on the login page — by default the reset link is printed to dvara-flightdeck logs (docker compose logs dvara-flightdeck). Configure SMTP with dvara.flightdeck.email.transport=smtp (or =resend for the Resend transactional API) for email delivery.