Skip to main content
This walkthrough assumes you have Docker installed plus API keys for at least one TTS/STT provider (Deepgram or ElevenLabs) and optional LiveKit credentials.
Prefer a managed LiveKit instance? Point LIVEKIT_URL at the internal signaling address and LIVEKIT_PUBLIC_URL at the client-facing domain.
1

Clone and prep configuration

git clone https://github.com/your-org/sayna.git
cd sayna
cp .env.example .env
You can keep using .env, but for local development it’s often clearer to generate a config file and pass it to Sayna:
server:
  host: "0.0.0.0"      # ENV: HOST
  port: 3001           # ENV: PORT

livekit:
  url: "ws://localhost:7880"              # ENV: LIVEKIT_URL
  public_url: "http://localhost:7880"     # ENV: LIVEKIT_PUBLIC_URL
  api_key: "devkey"                       # ENV: LIVEKIT_API_KEY
  api_secret: "secret"                    # ENV: LIVEKIT_API_SECRET

providers:
  deepgram_api_key: "your-deepgram-api-key"       # ENV: DEEPGRAM_API_KEY
  elevenlabs_api_key: "your-elevenlabs-api-key"   # ENV: ELEVENLABS_API_KEY
2

Start LiveKit + Redis

LiveKit needs Redis for state. Run both with Docker Compose:
services:
  redis:
    restart: always
    image: redis:alpine

  livekit:
    image: livekit/livekit-server:v1.9.1
    command: --dev --bind=0.0.0.0
    restart: always
    environment:
      LIVEKIT_CONFIG: |
        port: 7880
        log_level: info
        rtc:
          tcp_port: 7881
          port_range_start: 50000
          port_range_end: 60000
        redis:
          address: redis:6379
    ports:
      - "7880:7880"
      - "7881:7881"
Keep this stack running so Sayna can reach LiveKit on the internal network (ws://localhost:7880 or ws://livekit:7880 if you use the Docker Compose file).
3

Run Sayna locally

If you created config.yaml, run:
cargo run -- -c config.yaml
or simply cargo run when environment variables are already loaded (e.g., via .env).Prefer Docker? Add a Sayna service to the same Compose file so it shares the network with LiveKit:
services:
  sayna:
    build: .
    depends_on:
      - livekit
    environment:
      HOST: 0.0.0.0
      PORT: 3001
      LIVEKIT_URL: ws://livekit:7880
      LIVEKIT_PUBLIC_URL: http://localhost:7880
      LIVEKIT_API_KEY: devkey
      LIVEKIT_API_SECRET: secret
      DEEPGRAM_API_KEY: your-deepgram-api-key
      ELEVENLABS_API_KEY: your-elevenlabs-api-key
    ports:
      - "3001:3001"
Whether you use config files or env vars, make sure the Sayna container can resolve the LiveKit hostname (livekit) and expose port 3001 to your host machine.
4

Smoke test

curl http://localhost:3001/
curl http://localhost:3001/voices
Then connect a WebSocket client, send a config message, and queue a speak payload to hear a synthesized clip. Use /livekit/token to mint attendee tokens if you mirror audio into LiveKit.

Next steps