Skip to content

Self-Hosted Configuration

Self-hosted deployments require configuration for tokens, providers, networking, and browser connectivity. This page documents all environment variables and configuration options for the self-hosted stack.

Environment File Location

The stack reads configuration from a stack.env file in the workspace root (one level up from the stack/ directory):

bash
cp stack/stack.env.example stack.env

Required Variables

These variables must be set before starting the stack:

VariableDescriptionExample
ENCRYPTION_KEY32+ character secret for encrypting stored API keysabcd1234... (64 char hex)
ENGINE_API_KEYServer-side API key for engine authenticationmy-secure-api-key
JWT_SECRET32+ character secret for JWT token signingmy-jwt-secret-min-32-chars
CORE_BOOTSTRAP_PUBLISHABLE_KEYPublishable key for Core to auto-create on first bootvkey_... (64 char hex)
DEEPGRAM_API_KEYDeepgram API key for STT and TTSGet from deepgram.com
GROQ_API_KEY or OPENROUTER_API_KEYLLM provider API keyGet from provider console

Generating Secure Keys

Generate secure random keys for secrets:

bash
# 64-character hex string for ENCRYPTION_KEY and CORE_BOOTSTRAP_PUBLISHABLE_KEY
openssl rand -hex 32

# 32+ character random string for JWT_SECRET and ENGINE_API_KEY
openssl rand -base64 32

Provider Configuration

LLM Provider

Choose one LLM provider:

bash
# Option 1: Groq (default, fast)
LLM_PROVIDER=groq
GROQ_API_KEY=gsk_your_groq_key
GROQ_MODEL=openai/gpt-oss-20b

# Option 2: OpenRouter (100+ models)
LLM_PROVIDER=openrouter
OPENROUTER_API_KEY=sk-or-v1-your_key
OPENROUTER_MODEL=openrouter/healer-alpha

# Option 3: OpenAI-compatible gateway
LLM_PROVIDER=openai-compatible
OPENAI_COMPATIBLE_BASE_URL=http://host.docker.internal:8000/v1
OPENAI_COMPATIBLE_API_KEY=your_key
OPENAI_COMPATIBLE_MODEL=gpt-4o-mini

LLM Provider Variables:

VariableDefaultDescription
LLM_PROVIDERopenroutergroq, openrouter, or openai-compatible
GROQ_API_KEY-Groq API key
GROQ_MODELopenai/gpt-oss-20bGroq model ID
GROQ_WHISPER_MODELwhisper-large-v3Groq Whisper model for STT
OPENROUTER_API_KEY-OpenRouter API key
OPENROUTER_MODELopenrouter/healer-alphaOpenRouter model ID
OPENAI_COMPATIBLE_BASE_URLhttp://host.docker.internal:8000/v1Base URL for compatible gateway
OPENAI_COMPATIBLE_API_KEY-API key for compatible gateway
OPENAI_COMPATIBLE_MODELgpt-4o-miniModel ID for compatible gateway

STT/TTS Configuration

Deepgram is the default provider for both speech-to-text and text-to-speech:

bash
STT_PROVIDER=deepgram
DEEPGRAM_API_KEY=your_deepgram_key
DEEPGRAM_STT_MODEL=nova-3
DEEPGRAM_STT_LANGUAGE=en-US
TTS_PROVIDER=deepgram
DEEPGRAM_TTS_MODEL=aura-2-thalia-en

STT/TTS Variables:

VariableDefaultDescription
STT_PROVIDERdeepgramSpeech-to-text provider
DEEPGRAM_STT_MODELnova-3Deepgram STT model
DEEPGRAM_STT_LANGUAGEen-USSTT language code
TTS_PROVIDERdeepgramText-to-speech provider
DEEPGRAM_TTS_MODELaura-2-thalia-enDeepgram TTS voice model

VAD Configuration

Voice Activity Detection (VAD) detects when users start and stop speaking:

bash
VAD_PROVIDER=silero
VAD_ENABLED=true

VAD Variables:

VariableDefaultDescription
VAD_PROVIDERsileroVAD provider (silero or none)
VAD_ENABLEDtrueEnable server-side VAD

Bootstrap Configuration

Core auto-creates an app and publishable API key on first boot using these variables:

bash
CORE_BOOTSTRAP_APP_ID=default
CORE_BOOTSTRAP_APP_NAME=Local Stack App
CORE_BOOTSTRAP_APP_DESCRIPTION=Bootstrap app for the self-hosted Docker stack
CORE_BOOTSTRAP_API_KEY_LABEL=Local Stack Key
CORE_BOOTSTRAP_SCOPES=mint_ephemeral
CORE_BOOTSTRAP_ALLOWED_PROVIDERS=vowel-prime
CORE_BOOTSTRAP_ALLOWED_ENDPOINT_PRESETS=staging
CORE_BOOTSTRAP_DEFAULT_ENDPOINT_PRESET=staging
CORE_BOOTSTRAP_PUBLISHABLE_KEY=vkey_0123456789abcdef...

Bootstrap Variables:

VariableDefaultDescription
CORE_BOOTSTRAP_APP_IDdefaultApp ID to create
CORE_BOOTSTRAP_APP_NAMELocal Stack AppDisplay name
CORE_BOOTSTRAP_APP_DESCRIPTIONBootstrap app for the self-hosted Docker stackDescription
CORE_BOOTSTRAP_API_KEY_LABELLocal Stack KeyAPI key label
CORE_BOOTSTRAP_SCOPESmint_ephemeralComma-separated scopes
CORE_BOOTSTRAP_ALLOWED_PROVIDERSvowel-primeComma-separated allowed providers
CORE_BOOTSTRAP_ALLOWED_ENDPOINT_PRESETSstagingComma-separated allowed presets
CORE_BOOTSTRAP_DEFAULT_ENDPOINT_PRESETstagingDefault preset
CORE_BOOTSTRAP_PUBLISHABLE_KEY-Required. Plaintext publishable key to seed

The publishable key is what client applications use to request tokens from Core. It should be a 64-character hex string prefixed with vkey_.

Port Configuration

Override default ports when they conflict with existing services:

bash
CORE_HOST_PORT=3001
ENGINE_HOST_PORT=8788

Port Variables:

VariableDefaultDescription
CORE_HOST_PORT3000Host port for Core service
ENGINE_HOST_PORT8787Host port for Engine service

After changing ports, update the Core environment to reflect the new engine port:

bash
# In stack.env
ENGINE_URL=http://engine:8787
ENGINE_WS_URL=ws://localhost:8788/v1/realtime
ENDPOINT_PRESET_VOWEL_PRIME_STAGING_HTTP_URL=http://engine:8787
ENDPOINT_PRESET_VOWEL_PRIME_STAGING_WS_URL=ws://localhost:8788/v1/realtime

Runtime Config Ownership

The engine persists its runtime configuration as YAML at /app/data/config/runtime.yaml on the engine-data Docker volume. Environment variables in stack.env act as bootstrap defaults for the first boot and as fallback values when a key is missing from the YAML.

HTTP Config Endpoints

The engine exposes HTTP endpoints for inspecting and updating runtime configuration without rebuilding:

EndpointMethodDescription
/configGETRetrieve current runtime config
/configPUTUpdate runtime config
/config/validatePOSTValidate a config change
/config/reloadPOSTReload config from disk
/presetsGETList available presets

All config endpoints require the engine admin API key via Authorization: Bearer ${ENGINE_API_KEY}.

Example: Update Runtime Config

bash
# Get current config
curl http://localhost:8787/config \
  -H "Authorization: Bearer ${ENGINE_API_KEY}"

# Update a setting
curl -X PUT http://localhost:8787/config \
  -H "Authorization: Bearer ${ENGINE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"llm": {"provider": "groq", "model": "openai/gpt-oss-20b"}}'

# Validate before applying
curl -X POST http://localhost:8787/config/validate \
  -H "Authorization: Bearer ${ENGINE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"llm": {"provider": "openrouter"}}'

# Reload from disk
curl -X POST http://localhost:8787/config/reload \
  -H "Authorization: Bearer ${ENGINE_API_KEY}"

Core Configuration Areas

Provider Credentials

Store all provider API keys in stack.env. Core encrypts provider keys before storing them in its SQLite database using the ENCRYPTION_KEY.

Service URLs

Core needs to know how to reach the engine:

bash
# Internal Docker network URL (Core -> Engine)
ENGINE_URL=http://engine:8787

# External URL for clients (used in token responses)
ENGINE_WS_URL=ws://localhost:8787/v1/realtime

Token Issuance Settings

Control who can request tokens and which providers they can use:

  • CORE_BOOTSTRAP_SCOPES: Controls API key capabilities (mint_ephemeral, mint_trusted_session)
  • CORE_BOOTSTRAP_ALLOWED_PROVIDERS: Which voice providers can be used
  • CORE_BOOTSTRAP_ALLOWED_ENDPOINT_PRESETS: Which endpoint presets are available

Browser-Facing Origins

For CORS, Core accepts requests from any origin by default in development. In production, configure your reverse proxy to handle CORS policy.

Environment-Specific Configuration

Development

bash
TEST_MODE=true
NODE_ENV=development

Production

bash
TEST_MODE=false
NODE_ENV=production

Security Guidance

  • Rotate provider secrets regularly (every 90 days recommended)
  • Scope credentials to the environments that need them
  • Terminate TLS before exposing browser-facing endpoints
  • Avoid embedding long-lived credentials in any client bundle
  • Never commit stack.env to version control
  • Use STACK_ENV_FILE to switch between environment files for different stages

Complete Example Configuration

bash
# stack.env - Production Example

# === REQUIRED SECRETS ===
ENCRYPTION_KEY=your-64-char-hex-encryption-key
ENGINE_API_KEY=your-secure-server-api-key
JWT_SECRET=your-32-char-minimum-jwt-secret
CORE_BOOTSTRAP_PUBLISHABLE_KEY=vkey_your-64-char-hex-key

# === PROVIDER CREDENTIALS ===
DEEPGRAM_API_KEY=your-deepgram-key

# LLM Provider (pick one)
LLM_PROVIDER=groq
GROQ_API_KEY=gsk_your_groq_key

# === OPTIONAL OVERRIDES ===
CORE_HOST_PORT=3000
ENGINE_HOST_PORT=8787

# === BOOTSTRAP CONFIG ===
CORE_BOOTSTRAP_APP_ID=production-app
CORE_BOOTSTRAP_APP_NAME=Production Voice App
CORE_BOOTSTRAP_SCOPES=mint_ephemeral,mint_trusted_session
CORE_BOOTSTRAP_ALLOWED_PROVIDERS=vowel-prime