Skip to main content

Docker Quickstart

Get Dvara Gateway running with docker compose up in under 5 minutes.

Prerequisites

  • Docker 20.10+ with Compose v2
  • ~2 GB free disk space for the build

Quick Start (Standalone Mode)

No API keys needed — Docker runs in standalone mode by default (GATEWAY_MODE=standalone). This enables the mock provider, uses in-memory storage, and produces plain-text logs. No external dependencies (no PostgreSQL, no Redis) are required.

# Build and start both services
docker compose up -d

# Wait for healthy status (~30 seconds for first build)
docker compose ps

# Verify the gateway is running
curl http://localhost:8080/status

# Open the built-in test panel
open http://localhost:8080/try

# List available models
curl -s http://localhost:8080/v1/models | jq .

# Send a test chat request
curl -s -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "mock/test-model",
"messages": [{"role": "user", "content": "Hello!"}]
}' | jq .

# Open the admin UI
open http://localhost:8090

Adding Real Providers

Use the providers override to pass API keys from your environment:

# Set your keys
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...

# Start with real providers
docker compose -f docker-compose.yml \
-f examples/docker-compose/docker-compose.providers.yml up -d

# Verify providers are registered
curl -s http://localhost:8080/v1/models | jq '.data[].id'

Alternatively, use a .env file:

cp examples/docker-compose/.env.example examples/docker-compose/.env
# Edit examples/docker-compose/.env with your API keys

docker compose -f docker-compose.yml \
-f examples/docker-compose/docker-compose.providers.yml \
--env-file examples/docker-compose/.env up -d

Adding Ollama (Local Models)

Run local models via Ollama alongside the gateway:

docker compose -f docker-compose.yml \
-f examples/docker-compose/docker-compose.ollama.yml 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 .

You can combine both overrides:

docker compose -f docker-compose.yml \
-f examples/docker-compose/docker-compose.providers.yml \
-f examples/docker-compose/docker-compose.ollama.yml up -d

Admin UI

The gateway-ui service starts alongside the gateway server and provides a live traffic dashboard at http://localhost:8090. It uses actuator health probes for Docker health checks:

# Liveness check
curl http://localhost:8090/actuator/health/liveness

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

The UI connects to gateway-server automatically via GATEWAY_SERVER_URL and degrades gracefully if the server is unreachable. See Admin UI Guide for full documentation.

Using Pre-Built Images

Pre-built images are published to GitHub Container Registry:

# Pull the latest images
docker pull ghcr.io/kdhrubo/dvara/gateway-server:latest
docker pull ghcr.io/kdhrubo/dvara/gateway-ui:latest
docker pull ghcr.io/kdhrubo/dvara/mcp-proxy-server:latest

# Run the gateway server directly
docker run -p 8080:8080 \
-e OPENAI_API_KEY=sk-... \
ghcr.io/kdhrubo/dvara/gateway-server:latest

Available tags: latest (main branch), <version> (release tags, e.g. 1.0.0), sha-<short> (commit SHA).

Enterprise Mode (Docker Compose)

The enterprise overlay adds the MCP proxy and enables enterprise features. Requires a signed JWT license key (generate via the license-generator CLI tool).

# Set your license key
export GATEWAY_ENTERPRISE_LICENSE_KEY=eyJhbGci...

# Start all 3 services: enterprise server (8080), admin UI (8090), MCP proxy (8070)
docker compose -f docker-compose.yml -f docker-compose.enterprise.yml up -d

# Verify all services are healthy
docker compose -f docker-compose.yml -f docker-compose.enterprise.yml ps

# Check enterprise server
curl http://localhost:8080/status

# Check MCP proxy
curl http://localhost:8070/actuator/health/liveness

The enterprise overlay (docker-compose.enterprise.yml):

  • Swaps gateway-server to build from gateway-server/Dockerfile (includes all enterprise modules)
  • Adds mcp-proxy-server on port 8070
  • Passes GATEWAY_ENTERPRISE_LICENSE_KEY to both services

You can combine enterprise mode with provider overrides:

OPENAI_API_KEY=sk-... GATEWAY_ENTERPRISE_LICENSE_KEY=eyJ... \
docker compose -f docker-compose.yml \
-f docker-compose.enterprise.yml \
-f examples/docker-compose/docker-compose.providers.yml up -d

Rebuilding After Code Changes

docker compose build
docker compose up -d

Or rebuild a single service:

docker compose build gateway-server
docker compose up -d gateway-server

For enterprise builds:

docker compose -f docker-compose.yml -f docker-compose.enterprise.yml build
docker compose -f docker-compose.yml -f docker-compose.enterprise.yml up -d

Viewing Logs

# All services
docker compose logs -f

# Single service
docker compose logs -f gateway-server

Logs use plain-text format by default in Docker (standalone mode includes the log-plain profile).

You can also activate standalone mode without Docker:

GATEWAY_MODE=standalone ./mvnw -pl gateway-server spring-boot:run
# or
SPRING_PROFILES_ACTIVE=standalone ./mvnw -pl gateway-server spring-boot:run

Stopping

docker compose down

To also remove built images:

docker compose down --rmi local

Cloud Deploy

Pre-built deploy configs are included in the repository root for one-click deployment:

PlatformConfig FileDeploy
Renderrender.yamlDeploy to Render
Fly.iofly.tomlfly launch --copy-config && fly secrets set OPENAI_API_KEY=sk-... && fly deploy
Railwayrailway.jsonDeploy on Railway

All cloud targets default to standalone mode (in-memory, no database). To upgrade to full unlicensed mode, provision a PostgreSQL database and set GATEWAY_MODE=full with the DATABASE_URL.

Troubleshooting

Build fails with out-of-memory

Increase Docker's memory allocation to at least 4 GB in Docker Desktop settings.

Port already in use

Change the host port mapping in docker-compose.yml:

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 gateway-server env | grep -i api_key

Keys must be non-empty for providers to register.

Health check keeps failing

Check the logs for startup errors:

docker compose logs gateway-server | head -50

The gateway needs ~15-20 seconds to start. If it consistently fails, check for port conflicts or missing dependencies.