WebRTC with Livekit
The WebRTC conversation service and its componen
This guide walks you through deploying webrtc-server using https://github.com/Conv-AI/webrtc-server/tree/main . You’ll need two domains:
vm.example.com – main WebRTC server
vm-turn.example.com – TURN server
The repo supports two deployment methods and includes the build_vm_init.sh helper script to generate a vm_init.sh setup script.
TLS with Caddy
1. Networking Requirements
Please ensure the following ports are accessible on the server
443 - primary HTTPS and TURN/TLS
7881 - for WebRTC over TCP
3478/UDP - for TURN/UDP
50000-60000/UDP - for WebRTC over UDP
2. Configure TLS certificates for caddy
mkdir /opt/livekit/certsPlace certificates and configure caddy.yaml with cert locations and configure domains
3. Configure livekit.yaml
set turn domain, api key and api secret
Example generated script
#!/bin/sh
# generated by build_vm_init.sh
# This script will write all of your configurations to /opt/livekit.
# It'll also install LiveKit as a systemd service that will run at startup
# LiveKit will be started automatically at machine startup.
# create directories for LiveKit
mkdir -p /opt/livekit/caddy_data
mkdir -p /usr/local/bin
# Docker & Docker Compose will need to be installed on the machine
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
sh /tmp/get-docker.sh
curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod 755 /usr/local/bin/docker-compose
sudo systemctl enable docker
# docker-compose.yaml
cat << 'EOF' > /opt/livekit/docker-compose.yaml
# This docker-compose requires host networking, which is only available on Linux
# This compose will not function correctly on Mac or Windows
services:
caddy:
image: convaitech/caddyl4
command: run --config /etc/caddy.yaml --adapter yaml
restart: unless-stopped
network_mode: "host"
volumes:
- ./caddy.yaml:/etc/caddy.yaml
- ./caddy_data:/data
- ./certs:/certs
livekit:
image: convaitech/webrtc-server:v1.9.0
command: --config /etc/livekit.yaml
restart: unless-stopped
network_mode: "host"
volumes:
- ./livekit.yaml:/etc/livekit.yaml
redis:
image: redis:7-alpine
command: redis-server /etc/redis.conf
restart: unless-stopped
network_mode: "host"
volumes:
- ./redis.conf:/etc/redis.conf
EOF
# livekit config
cat << 'EOF' > /opt/livekit/livekit.yaml
port: 7880
bind_addresses:
- ""
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
enable_loopback_candidate: false
redis:
address: localhost:6379
username: ""
password: ""
db: 0
use_tls: false
sentinel_master_name: ""
sentinel_username: ""
sentinel_password: ""
sentinel_addresses: []
cluster_addresses: []
max_redirects: null
turn:
enabled: true
domain: lk-vm-turn.convai.com
tls_port: 5349
udp_port: 3478
external_tls: true
keys:
APITqAGB9qhyLvV: yzIAelkGy24QcPcJVNh8WGkObHFFK5JJIz2pXku3lsE
EOF
# caddy config
cat << 'EOF' > /opt/livekit/caddy.yaml
logging:
logs:
default:
level: INFO
storage:
"module": "file_system"
"root": "/data"
apps:
tls:
certificates:
load_files:
- certificate: "/certs/fullchain.pem"
key: "/certs/privkey.pem"
# - certificate: "/certs/lk-vm.convai.com.crt"
# key: "/certs/lk-vm.convai.com.key"
layer4:
servers:
main:
listen: [":443"]
routes:
- match:
- tls:
sni:
- "lk-vm-turn.convai.com"
handle:
- handler: tls
- handler: proxy
upstreams:
- dial: ["localhost:5349"]
- match:
- tls:
sni:
- "lk-vm.convai.com"
handle:
- handler: tls
connection_policies:
- alpn: ["http/1.1"]
- handler: proxy
upstreams:
- dial: ["localhost:7880"]
EOF
# update ip script
cat << 'EOF' > /opt/livekit/update_ip.sh
#!/usr/bin/env bash
ip=`ip addr show |grep "inet " |grep -v 127.0.0. |head -1|cut -d" " -f6|cut -d/ -f1`
sed -i.orig -r "s/\\\"(.+)(\:5349)/\\\"$ip\2/" /opt/livekit/caddy.yaml
EOF
# redis config
cat << 'EOF' > /opt/livekit/redis.conf
bind 127.0.0.1 ::1
protected-mode yes
port 6379
timeout 0
tcp-keepalive 300
EOF
# systemd service file
cat << 'EOF' > /etc/systemd/system/livekit-docker.service
[Unit]
Description=LiveKit Server Container
After=docker.service
Requires=docker.service
[Service]
LimitNOFILE=500000
Restart=always
WorkingDirectory=/opt/livekit
# Shutdown container (if running) when unit is started
ExecStartPre=/usr/local/bin/docker-compose -f docker-compose.yaml down
ExecStart=/usr/local/bin/docker-compose -f docker-compose.yaml up
ExecStop=/usr/local/bin/docker-compose -f docker-compose.yaml down
[Install]
WantedBy=multi-user.target
EOF
# Make update_ip.sh executable and run it
chmod 755 /opt/livekit/update_ip.sh
/opt/livekit/update_ip.sh
# Enable and start the service
systemctl enable livekit-docker
systemctl start livekit-docker
cat /opt/livekit/livekit.yamlNLB terminated TLS
Configure livekit.yaml turn domain, api key and secret
Networking Requirements Please ensure the following ports are accessible on the vm
7880 - primary server - tcp
5349 - TURN/TLS - tcp
7881 - for WebRTC over TCP
3478/UDP - for TURN/UDP
50000-60000/UDP - for WebRTC over UDP
3. VM target groups:
7880:TCP
5349:TCP
4. Create NLBs
NLB1- vm.example.com - Listening on TLS 443 - forward to 7880:TCP
NLB2- vm-turn.example.com - Listening on TLS 443 - 5349:TCP
Example generated script
#!/bin/sh
# generated by build_vm_init.sh
# This script will write all of your configurations to /opt/livekit.
# It'll also install LiveKit as a systemd service that will run at startup
# LiveKit will be started automatically at machine startup.
# create directories for LiveKit
mkdir -p /opt/livekit
mkdir -p /usr/local/bin
# Docker & Docker Compose will need to be installed on the machine
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
sh /tmp/get-docker.sh
curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod 755 /usr/local/bin/docker-compose
sudo systemctl enable docker
# docker-compose.yaml
cat << 'EOF' > /opt/livekit/docker-compose.yaml
# This docker-compose requires host networking, which is only available on Linux
# This compose will not function correctly on Mac or Windows
services:
livekit:
image: convaitech/webrtc-server:v1.9.0
command: --config /etc/livekit.yaml
restart: unless-stopped
network_mode: "host"
volumes:
- ./livekit.yaml:/etc/livekit.yaml
redis:
image: redis:7-alpine
command: redis-server /etc/redis.conf
restart: unless-stopped
network_mode: "host"
volumes:
- ./redis.conf:/etc/redis.conf
EOF
# livekit config
cat << 'EOF' > /opt/livekit/livekit.yaml
port: 7880
bind_addresses:
- ""
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
enable_loopback_candidate: false
redis:
address: localhost:6379
username: ""
password: ""
db: 0
use_tls: false
sentinel_master_name: ""
sentinel_username: ""
sentinel_password: ""
sentinel_addresses: []
cluster_addresses: []
max_redirects: null
turn:
enabled: true
domain: lk-vm-turn.convai.com
tls_port: 5349
udp_port: 3478
external_tls: true
keys:
APIfQ95orRbMckX: ebKy3EMXG6kYqjUSWXFMUkr4Ad64DAAyX5Oi2fAtpD9
EOF
# update ip script
cat << 'EOF' > /opt/livekit/update_ip.sh
#!/usr/bin/env bash
ip=`ip addr show |grep "inet " |grep -v 127.0.0. |head -1|cut -d" " -f6|cut -d/ -f1`
sed -i.orig -r "s/\\\"(.+)(\:5349)/\\\"$ip\2/" /opt/livekit/caddy.yaml
EOF
# redis config
cat << 'EOF' > /opt/livekit/redis.conf
bind 127.0.0.1 ::1
protected-mode yes
port 6379
timeout 0
tcp-keepalive 300
EOF
# systemd service file
cat << 'EOF' > /etc/systemd/system/livekit-docker.service
[Unit]
Description=LiveKit Server Container
After=docker.service
Requires=docker.service
[Service]
LimitNOFILE=500000
Restart=always
WorkingDirectory=/opt/livekit
# Shutdown container (if running) when unit is started
ExecStartPre=/usr/local/bin/docker-compose -f docker-compose.yaml down
ExecStart=/usr/local/bin/docker-compose -f docker-compose.yaml up
ExecStop=/usr/local/bin/docker-compose -f docker-compose.yaml down
[Install]
WantedBy=multi-user.target
EOF
# Make update_ip.sh executable and run it
chmod 755 /opt/livekit/update_ip.sh
/opt/livekit/update_ip.sh
# Enable and start the service
systemctl enable livekit-docker
systemctl start livekit-dockerWrbRTC Server
Once we have livekit setup completed, we can continue with the WebRTC Core service setup.
Image:
convaitech/onprem-webrtc-backend-service:latestEnvironment Variable Setup
Create a .env file in your system. Lets assume a webrtc-server.env file exists at /var/secrets. Fill the file with the required configurations as specified by the team. Here is some sample data..
// webrtc-server.env
OPENAI_API_KEY=sk-svcacct-HZBr4Pko...
GEMINI_API_KEY=AIz...
CLAUDE_API_KEY=sk-ant-api03-X...
MEM0_API_KEY=m0-nrnOH...
DATABASE_URL=postgresql+asyncpg://convai_user:<passowrd>@localhost:5432/convai_db
REDIS_URL=redis://localhost:6379
...
LIVEKIT_URL=ws://localhost:7880
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=secret
# App Config
ENABLE_ACTOR_POOLING=false
ENABLE_ROOM_POOLING=false
BOT_IMPLEMENTATION=openai
ENV=production
...Container Deployment:
Run the following docker command to start the server:
$ sudo docker run --rm \
--name core-service \
-p 8002:8000 \
-v "/home/convai/secrets/webrtc-secrets.env:/app/secrets/secrets.env:ro" \
convaitech/onprem-webrtc-backend-service:latest \
bash -lc "ray start --head && serve start --http-host 0.0.0.0 --http-port 8000 && serve run --route-prefix / server:api_server"Last updated