Skip to main content
Deploy Vexa as a single Docker container with no GPU requirements. Vexa Lite bundles all services into one image, managed by supervisord.
One-click platform deployments: For platform-specific guides (Fly.io, Railway, Render, etc.), see the vexa-lite-deploy repository.

Overview

Why Vexa Lite?
  • Single container — All services bundled, no multi-service orchestration
  • Stateless — All data stored in your database; easy to redeploy
  • No GPU required — Uses the Vexa remote transcription service
  • Built-in Redis — No external Redis needed (optional external Redis supported)
  • Interactive bots — TTS (text-to-speech) and virtual camera included

Included Services

Vexa Lite runs the following services internally via supervisord:
ServiceInternal PortDescription
API Gateway8056Main entry point (the only exposed port)
Admin API8057User and API token management
Bot Manager8080Bot lifecycle management (process orchestrator)
Transcription Collector8123Stores transcription segments in PostgreSQL
WhisperLive9090Transcription relay (routes to remote service)
MCP Service18888Model Context Protocol for Claude/Cursor
TTS Service8059Text-to-speech via OpenAI API
Redis6379Built-in message broker
XvfbVirtual display for headless browsers
PulseAudioAudio server for TTS playback
All internal services communicate over localhost. Only port 8056 is exposed externally.

Quick Start

Production: Remote Database

docker run -d \
  --name vexa \
  -p 8056:8056 \
  -e DATABASE_URL="postgresql://user:password@your-db-host:5432/vexa" \
  -e DB_SSL_MODE="require" \
  -e ADMIN_API_TOKEN="your-secret-admin-token" \
  -e TRANSCRIBER_URL="https://transcription.vexa.ai/v1/audio/transcriptions" \
  -e TRANSCRIBER_API_KEY="your-transcription-api-key" \
  -e OPENAI_API_KEY="sk-your-openai-key" \
  vexaai/vexa-lite:latest

Development: Local Database

# Create network
docker network create vexa-network

# Start PostgreSQL
docker run -d \
  --name vexa-postgres \
  --network vexa-network \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=your_password \
  -e POSTGRES_DB=vexa \
  -p 5432:5432 \
  postgres:latest

# Start Vexa Lite
docker run -d \
  --name vexa \
  --network vexa-network \
  -p 8056:8056 \
  -e DATABASE_URL="postgresql://postgres:your_password@vexa-postgres:5432/vexa" \
  -e ADMIN_API_TOKEN="your-secret-admin-token" \
  -e TRANSCRIBER_URL="https://transcription.vexa.ai/v1/audio/transcriptions" \
  -e TRANSCRIBER_API_KEY="your-transcription-api-key" \
  -e OPENAI_API_KEY="sk-your-openai-key" \
  vexaai/vexa-lite:latest
The container automatically runs database migrations on startup. Fresh databases are initialized with the full schema.

Environment Variables

Required

DATABASE_URL
string
required
PostgreSQL connection string. Supports both postgresql:// and postgres:// schemes.Example: postgresql://user:pass@host:5432/vexaAlternatively, set individual variables: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD.
ADMIN_API_TOKEN
string
required
Secret token for admin operations (creating users, minting API tokens).
TRANSCRIBER_URL
string
required
Transcription service endpoint.Default: https://transcription.vexa.ai/v1/audio/transcriptions
TRANSCRIBER_API_KEY
string
required
API key for the transcription service. Get yours from vexa.ai/dashboard/api-keys.

Database

You can use DATABASE_URL or individual variables. If both are provided, DATABASE_URL takes precedence.
DB_HOST
string
default:"localhost"
PostgreSQL hostname.
DB_PORT
string
default:"5432"
PostgreSQL port.
DB_NAME
string
default:"vexa"
Database name.
DB_USER
string
default:"postgres"
Database user.
DB_PASSWORD
string
Database password.
DB_SSL_MODE
string
default:"disable"
SSL mode for database connections. Set to require for cloud-hosted databases (Supabase, Neon, AWS RDS, etc.).

Redis

Vexa Lite includes a built-in Redis server. If REDIS_HOST is localhost or unset, the internal Redis is used automatically. To use an external Redis, set REDIS_HOST to your Redis server address.
REDIS_HOST
string
default:"localhost"
Redis hostname. Set to an external address to use external Redis instead of the built-in server.
REDIS_PORT
string
default:"6379"
Redis port.
REDIS_URL
string
Full Redis URL. If provided, individual Redis vars are parsed from it.Example: redis://user:password@redis-host:6379/0

Interactive Bots (TTS & Virtual Camera)

The OpenAI TTS dependency is temporary. A fully local TTS engine (no external API keys required) is planned — see issue #130.
OPENAI_API_KEY
string
OpenAI API key for text-to-speech (temporary — will be replaced by local TTS, see #130). Required for the /speak command to work. Without this, bots can still join meetings and transcribe, but TTS will be unavailable.

Recording Storage

STORAGE_BACKEND
string
default:"local"
Recording storage backend: local, minio, or s3.
LOCAL_STORAGE_DIR
string
default:"/var/lib/vexa/recordings"
Directory for local recording storage. Mount a volume here for persistence.
For STORAGE_BACKEND=s3:
VariableDefaultDescription
AWS_REGIONus-east-1AWS region
AWS_ACCESS_KEY_IDAWS access key
AWS_SECRET_ACCESS_KEYAWS secret key
S3_BUCKETS3 bucket name
S3_ENDPOINTCustom S3 endpoint (for non-AWS providers)
S3_SECUREtrueUse HTTPS for S3 connections
For STORAGE_BACKEND=minio:
VariableDefaultDescription
MINIO_ENDPOINTMinIO server endpoint (e.g., minio:9000)
MINIO_ACCESS_KEYMinIO access key
MINIO_SECRET_KEYMinIO secret key
MINIO_BUCKETvexa-recordingsMinIO bucket name
MINIO_SECUREfalseUse HTTPS for MinIO connections

Transcription

WHISPER_BACKEND
string
default:"remote"
Transcription backend. Use remote to route audio to the Vexa transcription service (recommended). Use faster_whisper for local CPU-based transcription (slow, development only).
WHISPER_MODEL_SIZE
string
default:"tiny"
Whisper model size when using local transcription (WHISPER_BACKEND=faster_whisper). Options: tiny, base, small, medium.
SKIP_TRANSCRIPTION_CHECK
string
default:"false"
Set to true to skip the startup connectivity check to the transcription service. The URL and API key are still required but won’t be validated at startup.

Logging

LOG_LEVEL
string
default:"info"
Log level for all services. Options: debug, info, warning, error.

Health Check

The container includes a built-in health check that polls the API Gateway:
GET http://localhost:8056/docs
  • Interval: 30s
  • Timeout: 10s
  • Start period: 90s (allows services to initialize)
  • Retries: 3
Use this with your orchestrator’s health check mechanism:
# Check container health
docker inspect --format='{{.State.Health.Status}}' vexa

Recording Storage

For production, use object storage so recordings persist across container restarts:
docker run -d \
  --name vexa \
  -p 8056:8056 \
  -e STORAGE_BACKEND=s3 \
  -e AWS_ACCESS_KEY_ID="your-key" \
  -e AWS_SECRET_ACCESS_KEY="your-secret" \
  -e S3_BUCKET="vexa-recordings" \
  -e AWS_REGION="us-east-1" \
  -e DATABASE_URL="postgresql://user:pass@host/vexa" \
  -e ADMIN_API_TOKEN="your-admin-token" \
  -e TRANSCRIBER_URL="https://transcription.vexa.ai/v1/audio/transcriptions" \
  -e TRANSCRIBER_API_KEY="your-api-key" \
  vexaai/vexa-lite:latest
For local development, mount a volume:
docker run -d \
  -v vexa-recordings:/var/lib/vexa/recordings \
  ...
For the full storage matrix, see Recording storage.

Build from Source

To build the image locally from the Vexa repository:
git clone https://github.com/Vexa-ai/vexa.git
cd vexa/docker/lite
make build
This produces a vexa-lite:dev image. See make help for additional commands (push, set-latest, etc.).

Database Setup

  1. Create a project at supabase.com
  2. Click Connect on the project page
  3. Select method: Session pooler
  4. Copy the connection string
  5. Set DB_SSL_MODE=require
  1. Create a project at neon.tech
  2. Copy the connection string from the dashboard
  3. Set DB_SSL_MODE=require
docker network create vexa-network

docker run -d \
  --name vexa-postgres \
  --network vexa-network \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=your_password \
  -e POSTGRES_DB=vexa \
  -p 5432:5432 \
  postgres:latest
Then run Vexa Lite with --network vexa-network and DB_HOST=vexa-postgres.

Next Steps