Skip to main content
Version: 1.8.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.

These stacks run the Enterprise platform and include PostgreSQL for Flightdeck. From 1.8.2 the gateway has no database: it enrols with Flightdeck using DVARA_ENROLMENT_SECRET, reads its configuration from Flightdeck as a signed bundle, and spools its audit and usage records to the gateway-data volume, which it ships to Flightdeck. See How the gateway runs without a database. The separate Open Source distribution does not use these Compose files and needs no database; follow the Open Source distribution quickstart.

Pre-built images​

ImageWhat it isAccess
ghcr.io/dvarahq/dvara-gateway:1.8.5Data plane (:8080) — serves /v1/*, /mcp/* and /a2a/*Public
ghcr.io/dvarahq/dvara-flightdeck:1.8.5Role-aware control plane (:8090)Public

Two images, both public. There is one artifact per app. The license decides the posture and the limits, 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.8.5).

One Enterprise image set, two postures

The public dvara-gateway and dvara-flightdeck images run the Enterprise platform. Without a licence key they start in the non-production Development posture, which serves every feature, including the MCP and A2A paths, within 3 workspaces and 100,000 governed calls a month. A valid licence selects Production and removes those limits in the same images. There are no private MCP, A2A, Community, or -ee images.

The Open Source distribution is a separate Java distribution, not a mode of these images. See capability availability.

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/. From 1.8.2 the /mcp and /a2a paths serve on :8080 with or without a licence.

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.

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 registered provider live on a best-effort basis, so the list is not a catalogue DVARA maintains. A provider that fails discovery is omitted from the otherwise successful response. If data is empty, check that the key variables reached the container with docker compose exec dvara-gateway env | grep API_KEY. See Provider Setup for the full discovery contract.

The call requires a workspace API key. Add -H "Authorization: Bearer $DVARA_API_KEY", using a key created in Flightdeck for the quick-start or multi-provider stack.

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 the Enterprise platform entirely locally with no provider API keys or outbound LLM calls. Add a licence only for production rights and support; see Licensing.

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

From 1.8.2 the MCP and A2A planes serve with or without a licence: same container, same port, same health probe. Neither plane is included in the Open Source distribution.

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 Flightdeck.

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 the DVARA-specific secrets below in addition to provider keys + DB_PASSWORD (Flightdeck's database password; the gateway has no database). 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_KEYOptional. From 1.8.2 Flightdeck copies it into its licence store once, when none is stored; Gateway containers ignore it. Prefer the License page in Flightdeck.Missing starts Development. A value that does not verify is not stored.
DVARA_ENROLMENT_SECRETFrom 1.8.2. The shared secret the gateway enrols with Flightdeck by, to get its certificate for Flightdeck's /internal channel and the key that verifies config bundles. The same value on both services, at least 32 characters (openssl rand -base64 32).Compose refuses to start the stack
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, Enterprise /actuator/license, and every authenticated actuator path except prometheusEvery authenticated actuator request returns 401
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 chainRequired from 1.8.0. DVARA no longer generates it. Set your own value (openssl rand -base64 32), the same on every gateway and on Flightdeck. On a production Spring profile a process refuses to start without it; on the default profile it starts with only a warning. Never use a published placeholder value: the gateway accepts one without a warning.

Set the A2A push callback URL​

From 1.8.5 A2A push notifications go through the gateway. The gateway needs its own URL, as peer agents reach it, in A2A_PUSH_CALLBACK_BASE_URL. Until it is set, every A2A push config is refused with 503 A2A_PUSH_NOT_AVAILABLE, except in a workspace that keeps direct delivery. The LLM path does not need it.

Add it to the gateway service in your docker-compose.override.yml. A peer on the same Compose network reaches the gateway by its service name; a peer anywhere else needs the gateway's public URL:

services:
dvara-gateway:
environment:
A2A_PUSH_CALLBACK_BASE_URL: https://gateway.example.com

See Receive push notifications through DVARA.

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 (application state and PostgreSQL)

Gateway connectivity is deliberately excluded from Flightdeck readiness. Check it in System Status.

Stopping​

docker compose down # stop, keep data
docker compose down -v # stop and delete the volumes: PostgreSQL and the gateway's spool

Stop with docker compose down (or stop), not by killing containers. On a normal stop the gateway flushes its spool to Flightdeck first; deleting the gateway-data volume discards any records it has not shipped yet.

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.

The gateway refuses to start and names a setting​

From 1.8.2 the gateway has no database, and it checks its settings at startup. It refuses to start, and names the setting, when:

  • it has no DVARA_DATA_PLANE_CONTROL_PLANE_BASE_URL (Flightdeck's /internal address) or no DVARA_LLM_GATEWAY_LOCAL_STORE_PATH (its spool);
  • it is given SPRING_DATASOURCE_URL or a bootstrap file. Database settings and DVARA_BOOTSTRAP_FILE belong on dvara-flightdeck only.

A compose file written for 1.8.1 or earlier gives the gateway a database. Start again from one of the dvara-examples stacks rather than editing it by hand.

The gateway cannot enrol​

The gateway enrols with Flightdeck when it starts, so Flightdeck has to be healthy first. Check that DVARA_ENROLMENT_SECRET is set to the same value for both services, and that the gateway's base URL uses a name in Flightdeck's DVARA_INTERNAL_ENROLMENT_SERVER_NAMES:

docker compose logs dvara-gateway | grep -i enrol

Health check keeps failing​

docker compose logs dvara-gateway | head -50

Flightdeck runs its database migrations on first boot, and the gateway starts only after Flightdeck is healthy and the gateway has enrolled, so allow a minute on the first run. If it consistently fails, check for port conflicts.

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.