Bedrud, gerçek zamanlı video ve ses iletişimini yönetmek için LiveKit kullanır. LiveKit SFU (Seçici İletim Birimi) medya sunucusunu sağlar; Bedrud ise kimlik doğrulama, oda yönetimi ve yönetici kontrollerini üstlenir.
Gömülü ve Harici Modlar
Bedrud iki LiveKit dağıtım modunu destekler:
- Gömülü Mod (Varsayılan): Arka uç, bir LiveKit sunucu sürecini dahili olarak başlatır ve yönetir. Ek bir altyapı gerekmez - arka uç LiveKit süreç yaşam döngüsünü halleder.
- Harici Mod: Bedrud ayrı bir LiveKit sunucusuna veya kümesine bağlanır. Bu, yatay ölçeklendirme veya yönetilen bir LiveKit Cloud örneği kullanıldığında faydalıdır.
Harici Modu Yapılandırma
Harici bir LiveKit sunucusu kullanmak için config.yaml dosyasında şu anahtarları ayarlayın:
livekit:
host: "wss://livekit.example.com:7880" # Client WebSocket URL (ws:// or wss://)
internalHost: "https://livekit.example.com:7880" # Server-to-server API URL
apiKey: "your-api-key"
apiSecret: "your-api-secret"
external: true # Skip embedded LiveKit startup
skipTLSVerify: false # Set true if LiveKit uses self-signed certsembedded false olduğunda, Bedrud gömülü LiveKit ikili dosyasını başlatmayı atlar. API anahtarı ve gizli anahtar, harici sunucunun kimlik bilgileriyle eşleşmelidir.
LiveKit küme kurulumu ve yapılandırması için LiveKit dokümantasyonuna bakın.
Webhook Yapılandırması (Yalnızca Harici)
Harici bir LiveKit sunucusu kullanırken, LiveKit’in Bedrud’a katılımcı bağlantı kesilmeleri ve oda kapanışları hakkında bildirim gönderebilmesi için webhook’ları yapılandırmanız gerekir. Webhook’lar olmadan, veritabanı durumu güncelliğini yitirir.
Uç Nokta: https://<your-domain>/api/livekit/webhook
Kimlik Doğrulama: LiveKit’in JWT imzasını kullanır — yukarıda yapılandırdığınız aynı apiKey/apiSecret. Ayrı bir gizli anahtar gerekmez.
LiveKit Cloud: Ayarlar → Webhooks → Yeni webhook oluştur. Uç nokta URL’sini girin ve API anahtarınızı seçin.
Kendi sunucunuzda LiveKit: LiveKit YAML yapılandırmanıza (örn. livekit.yaml) ekleyin:
webhook:
urls: ["https://bedrud.example.com/api/livekit/webhook"]
api_key: "your-api-key"Düzgün yapılandırılmış bir webhook olmadan, participant_disconnected ve room_finished olayları Bedrud’a iletilmez. Yönetici panosu güncel olmayan katılımcı verileri gösterebilir ve odalar otomatik olarak temizlenmez.
LiveKit Sürüm Uyumluluğu
Bedrud’un gömülü LiveKit modu uyumlu bir yapılandırmayı otomatik olarak oluşturur. Ancak, harici bir LiveKit sunucusunu kendiniz barındırıyorsanız, LiveKit sürümleri arasındaki kırıcı değişikliklerin farkında olun:
- LiveKit v1.12+ yapılandırmasından üst düzey
tlsalanını kaldırdı. LiveKit YAML’ınızdatls:kullanıyorsanız, kaldırın. Bedrud yapılandırmasındainternalHostiçinhttp://vehostiçinws://yapılandırın. TURN TLS,turn:bölümü altında hâlâ desteklenmektedir. - LiveKit v1.11 ve öncesi üst düzeyde
tls:destekler.internalHostiçinhttps://vehostiçinwss://kullanın.
Emin değilseniz, livekit-server --version ile LiveKit sunucu sürümünüzü kontrol edin ve LiveKit sürüm notlarına başvurun.
Gömülü Yapılandırma Oluşturma (Embedded Config Generation)
TLS gömülü modda etkinleştirildiğinde, Bedrud geçici bir LiveKit YAML yapılandırması oluşturur (/tmp/bedrud-livekit-*.yaml):
- TURN etkin,
domainserver.host’tan otomatik ayarlanır,udp_port: 3478,tls_port: 5349, sunucunun TLS sertifikası TURN/TLS için yeniden kullanılır node_ipşu sırayla çözülür:livekit.nodeIP→server.host→ giden IP otomatik algılamabind_addressesatlanır (LiveKit varsayılan olarak tüm arayüzlere bağlanır)
Geçici dosya, LiveKit işlemi sona erdiğinde temizlenir. Statik bir yapılandırma ile otomatik oluşturmayı atlamak için livekit.configPath veya LIVEKIT_CONFIG_PATH ayarlayın.
Nasıl Çalışır
1. Oda Oluşturma
Bir kullanıcı Bedrud’da oda oluşturduğunda, sunucu hemen bir LiveKit odası oluşturmaz. LiveKit odaları ilk katılımcı katıldığında talep üzerine oluşturulur.
2. Katılım Jetonları
Bir kullanıcı bir toplantıya katıldığında:
-
Ön uç
/api/room/joinuç noktasına bir istek gönderir. -
Arka uç, kullanıcın o odaya katılma izni olduğunu doğrular.
-
Arka uç, API Anahtarını ve Gizli Anahtarını kullanarak imzalı bir JWT (Katılım Jetonu) üretir.
-
Jeton şunları içerir:
- Oda adı.
- Kullanıcının kimliği (görünen ad).
- İzinler - örneğin, kullanıcının ses yayımlayıp yayımlayamayacağı veya ekranını paylaşabileceği.
-
Ön uç bu jetonu alır ve doğrudan LiveKit medya portuna (varsayılan
7880) bağlanır.
3. Oda Kontrolleri (Yönetici)
Arka uç, yönetimsel eylemleri gerçekleştirmek için LiveKit Go SDK’sını kullanır:
- Atma: Bir katılımcının bağlantısını keser.
- Sessize Alma: Bir katılımcının mikrofonunu zorla sessize alır.
- İzinler: Bir katılımcının gerçek zamanlı olarak neler yapabileceğini değiştirir.
Ağ Mimarisi
- API Portu (8090/443): HTTP isteklerini ve arama kurulumu için WebSocket sinyalleşmesini yönetir.
- Medya Portu (7880): WebRTC protokollerini kullanarak video ve ses verilerini yönetir. UDP engellendiğinde ICE/TCP yedek portu olarak 7881 kullanılır.
- TURN Portu (3478 UDP / 5349 TLS): Kısıtlayıcı NAT veya güvenlik duvarları arkasındaki istemciler için medyayı aktarır. Bkz. TURN Sunucu Kılavuzu.
Güvenlik duvarı ve port gereksinimleri için bkz. WebRTC Bağlantısı.
Troubleshooting
Startup & Config Crashes
| Symptom | Cause | Fix |
|---|---|---|
Container crash-loops, logs could not resolve external IP | use_external_ip: true without explicit node_ip in Docker | Set node_ip: <lan-ip> under rtc: and use_external_ip: false |
LiveKit exits with TURN domain required on v1.12+ | turn.tls_port is set but no domain or TLS cert/key | Add domain: under turn:, provide cert_file/key_file, or remove tls_port for UDP-only TURN |
field tls not found on startup | LiveKit v1.12+ removed top-level tls: config field | Remove tls: block from LiveKit YAML; use http:// / ws:// in Bedrud config |
LIVEKIT_CONFIG env var not picked up | Entrypoint doesn’t parse env var (pre-v1.7 or custom entrypoint) | LiveKit reads LIVEKIT_CONFIG natively since v1.7 — verify version; pass via --config-body only if needed |
Docker: --config-body via sh -c fails with flag provided but not defined: -c | Image entrypoint is /livekit-server directly — command gets appended, not wrapped by shell | Don’t use a shell wrapper, LIVEKIT_CONFIG env var is supported natively by the binary |
Docker Compose: $LIVEKIT_CONFIG expands to empty string | Compose substitutes $VAR from host environment, not container | Use $$LIVEKIT_CONFIG to escape docker-compose variable substitution |
YAML parsing error from LIVEKIT_CONFIG | Incorrect YAML indentation or syntax | Validate: docker run --rm -e LIVEKIT_CONFIG livekit-server --config-body "$LIVEKIT_CONFIG" |
Connectivity
| Symptom | Cause | Fix |
|---|---|---|
| Admin dashboard shows “LiveKit disconnected” | Bedrud can’t reach LiveKit HTTP API | Verify internalHost in config; run curl http://<internalHost>/ from Bedrud host; check firewall |
| Token generated but client connection times out | LiveKit WebSocket unreachable from browser | Check host in livekit: config (must be reachable by clients); verify DNS/firewall; test with wscat |
| Embedded LiveKit not starting | Missing binary or permission | Ensure internal/livekit/bin/livekit-server exists (even empty file for build); check Bedrud server logs |
| Port 7880 already in use | Another process on same port | Change livekit.port or use different Docker port mapping |
| Redis connection fails in LiveKit logs | Redis unreachable or wrong address | Verify redis.address: in LiveKit YAML; check container network connectivity |
curl http://127.0.0.1:7880 returns connection refused | LiveKit crashed during startup | Check docker logs / journalctl; look for RTC/TURN validation errors near the bottom of the log |
| Token expired before client connected | Short JWT validity window | Request a fresh token via POST /api/room/join before each connection attempt |
Media & TURN
| Symptom | Cause | Fix |
|---|---|---|
| Participants join but no audio/video | UDP port range blocked or wrong node_ip | Open UDP 50000-60000; verify node_ip is the externally reachable address |
| Clients behind NAT can’t connect | TURN not configured or ports blocked | Enable TURN; open UDP 3478 (and TCP 5349 for TLS); verify TURN domain resolves |
Could not resolve external IP on startup (non-Docker) | No STUN internet access or DNS failure | Set explicit node_ip and use_external_ip: false |
| Self-signed cert errors with external LiveKit | Bedrud’s skipTLSVerify is false | Set skipTLSVerify: true in Bedrud’s livekit: config |
| Clients connect via relay unnecessarily | node_ip is a private IP behind NAT | Set node_ip to the public IP or use use_external_ip: true with STUN access |
| TURN relay not used by clients | Direct WebRTC path is working (expected) | Check chrome://webrtc-internals — srflx candidates = direct path, no TURN needed |
Webhook & State
| Symptom | Cause | Fix |
|---|---|---|
| Database shows stale active participants after disconnect | Webhook not configured for external LiveKit | Add webhook: block to LiveKit YAML with URL https://<domain>/api/livekit/webhook |
| Participants never marked inactive | Firewall blocking webhook delivery from LiveKit to Bedrud | Check LiveKit logs for webhook delivery errors; ensure port 443/8090 is reachable from LiveKit |
| Room not cleaned up after all leave | empty_timeout / departure_timeout too high | Reduce values in LiveKit YAML room: section |
Recording (Egress)
Bedrud uses LiveKit’s RoomCompositeEgress API to record rooms as MP4 files.
Prerequisites
-
Redis — LiveKit egress requires Redis for coordinating egress workers. Without Redis,
StartRoomCompositeEgressreturns permission errors. -
Egress S3 storage (external mode only) — For external LiveKit, you must configure an
egress:section in your LiveKit YAML so recordings are stored to durable S3-compatible storage. Otherwise theFileURLis a local path unreachable from Bedrud.egress: s3: access_key: "your-s3-access-key" secret_key: "your-s3-secret-key" endpoint: "http://minio:9000" bucket: "bedrud-recordings" region: "us-east-1" force_path_style: true
Troubleshooting: Recording
| Symptom | Cause | Fix |
|---|---|---|
twirp error unauthenticated: permissions denied when starting recording | Egress JWT missing Room field in grant | Update egressAuthContext to include Room: roomName in the VideoGrant |
twirp error unauthenticated: permissions denied even with valid API key | Redis not configured for LiveKit, or egress workers unavailable | Add redis: section to LiveKit YAML; ensure Redis is healthy |
Recording starts but FileURL is a local path (e.g., /tmp/...) | No egress: S3 config — LiveKit writes to worker temp dir | Add egress.s3: block to LiveKit YAML pointing to S3-compatible storage |
process_recording job fails to download | External LK’s file URL points to inaccessible local path | Configure egress S3 so LiveKit produces S3 URLs |
See also the TURN Server Guide for TURN-specific troubleshooting, WebRTC Connectivity for STUN/ICE/firewall debugging, and Installation Troubleshooting for port/perm/setup issues.
Ayrıca bakınız
- TURN Sunucu Kılavuzu - TURN mimarisi, yapılandırma, TLS ve sorun giderme
- WebRTC Bağlantısı - tam STUN/ICE/TURN/SFU bağlantı yığını
- Mimari Genel Bakış - tam sistem mimarisi