The gateway is distributed as a Docker image on Docker Hub.
Prerequisites
Docker and Docker Compose
Deploy standalone
In this setup, the gateway manages its own database, API keys, users, budgets, and usage tracking. You provide the LLM provider credentials directly.
1. Create a config file
cp config.example.yml config.yml
Edit config.yml with at least a master key and one provider:
database_url: "postgresql://gateway:gateway@postgres:5432/gateway"
host: "0.0.0.0"
port: 8000
master_key: "your-secret-master-key"
providers:
openai:
api_key: "sk-..."
2. Start the services
docker compose up -d
This starts two services:
gateway on port 8000
postgres on port 5433 (host) / 5432 (container)
3. Verify
curl http://localhost:8000/health
You should get {"status": "healthy"}.
Check readiness as well:
curl http://localhost:8000/health/readiness
Then verify an authenticated management call with your master key:
curl http://localhost:8000/v1/keys \
-H "Otari-Key: Bearer <your-master-key>"
Deploy with Otari
When connected to Otari, the gateway delegates provider routing, authentication, and usage tracking to otari.ai. No local database or provider credentials are needed.
1. Create a minimal config file
host: "0.0.0.0" port: 8000
No providers block, no database_url, no master_key.
2. Set your otari.ai credentials
You need your gateway token from your otari.ai account.
Pass them as environment variables. Create a .env file:
OTARI_AI_TOKEN=gw_your_token_here
3. Start the gateway
docker run --rm \
-p 8000:8000 \
--env-file .env \
-v "$(pwd)/config.yml:/app/config.yml:ro" \
mzdotai/otari:latest \
gateway serve --config /app/config.yml
No postgres container is needed -- otari.ai handles storage.
4. Verify
curl http://localhost:8000/health
The response includes platform reachability status:
{"status": "healthy", "mode": "platform", "platform_reachable": "yes"}Check readiness:
curl http://localhost:8000/health/readiness
Then verify a chat request using an otari.ai user token:
curl http://localhost:8000/v1/chat/completions \
-H "Authorization: Bearer <your-otari-user-token>" \
-H "Content-Type: application/json" \
-d '{
"model": "openai:gpt-4o",
"messages": [{"role": "user", "content": "Say hello in one short sentence."}]
}'
Optional services
The gateway supports two opt-in services via Docker Compose profiles.
Code execution sandbox
A sandboxed Python REPL for code_execution tool calls:
docker compose --profile code-exec up -d
Web search
A SearXNG-based web search backend for web_search tool calls:
docker compose --profile web-search up -d
Both profiles can be combined:
docker compose --profile code-exec --profile web-search up -d
When a profile is not running, the gateway returns a 502 to requests that try to use that tool.
Environment variables
Provider API keys can be passed as environment variables instead of putting them in config.yml:
Variable | Description |
| OpenAI API key |
| Anthropic API key |
| Mistral API key |
| Google Gemini API key |
| Gateway server bind port (default: |
| Master key for management endpoints |
| otari.ai gateway token |
See Configuration for the full reference.
Source: mozilla-ai/otari/docs/deployment.md
