================================================================================ NOVA ZEKA — Canlı yayın altyapısı (tek alan adı: novazeka.com.tr + LiveKit self-host) Sunucu IP (örnek A kaydı): 77.245.158.122 ================================================================================ A) DNS (alan adı sağlayıcınızda) Yalnızca kök alan yeterli — ayrı livekit.* kaydı GEREKMEZ. 1) novazeka.com.tr → 77.245.158.122 (@ / kök ve gerekirse www) B) Güvenlik duvarı (ufw veya panel) - 443/tcp, 80/tcp - 7881/tcp - 50000:60000/udp C) LiveKit (aynı VPS’te novazeka/livekit-selfhost) cd .../novazeka/livekit-selfhost Kayıt dizini = PHP’nin baktığı public_html …/livekit-selfhost/recordings ile BİR olmalı (Egress -v …:/out). cp .env.example .env nano .env → EGRESS_HOST_RECORDINGS_DIR=/home/KULLANICI/public_html/developer.novazeka.com.tr/novazeka/livekit-selfhost/recordings (veya ana site recordings yolu; PHP LIVEKIT_RECORDINGS_HOST_PATH* ile aynı mutlak yol) .env’deki yol için: mkdir -p …/livekit-selfhost/recordings && chown -R novazekacom:novazekacom …/recordings && chmod 775 …/recordings docker compose up -d Eski hata: Egress’i /root/livekit-recordings’e bağlamak — PHP public_html arar → 404. Ya .env yolunu kullanın ya da dosyaları taşıyın. Reverse proxy (443) — iki desteklenen model: C1) Nginx kök yol (klasik): /rtc ve /twirp → 127.0.0.1:7880 - Dosya: nginx-livekit-novazeka-root.snippet.conf - novazeka.com.tr 443 server bloğuna include edin (genel location / ve PHP’den ÖNCE). - http { } içinde yoksa map $http_upgrade $connection_upgrade { ... } ekleyin (dosya başındaki yorum). - nginx -t && systemctl reload nginx C2) Apache + aynı domain altında prefix (önerilen: Flutter localhost CORS sorununu azaltır) - Dosya: apache-livekit-novazeka-prefix.conf.example - İçeriğini novazeka.com.tr için aktif içine ekleyin. - a2enmod proxy proxy_http proxy_wstunnel headers rewrite ssl - apachectl -t && systemctl reload apache2 (veya httpd) (İsteğe bağlı) Eski kurulum: ayrı alt alan livekit.novazeka.com.tr → nginx-wss.novazeka.com.tr.conf D) PHP (novazeka) — repoda varsayılan - config/livekit_local.php → LIVEKIT_URL=wss://novazeka.com.tr/novazeka/livekit (secret’lar livekit.yaml ile aynı) - Canlı sunucuda bu dosyayı güncelledikten sonra php-fpm restart (opcache) developer.novazeka.com.tr ve localhost (Flutter dev): - Token API’si hangi sunucudaysa oradaki livekit_local.php geçerlidir. - C2 (Apache prefix) kullanıyorsanız: istemci sinyalleşmeyi aynı domain altında yapar (https://novazeka.com.tr/novazeka + wss://novazeka.com.tr/novazeka/livekit). - C1 (Nginx kök /rtc) kullanıyorsanız: Flutter localhost ile çalışırken /rtc/validate için CORS header’ları şarttır; aksi halde tarayıcı "Failed to fetch" verir. E) Flutter web canlı derleme ve yükleme cd web flutter build web --release --base-href=/novazeka/ --no-source-maps build/web/ içeriğini hosting’de novazeka.com.tr üzerindeki /novazeka/ köküne yükleyin (mevcut build_and_deploy_to_novazeka.bat ile uyumlu) F) Doğrulama - https://novazeka.com.tr/novazeka/ açılır - Admin → Canlı Yayınlar: .../admin/live-streams - Yayına gir: - C1: wss://novazeka.com.tr/rtc (Nginx → 127.0.0.1:7880) - C2: wss://novazeka.com.tr/novazeka/livekit/rtc (Apache → 127.0.0.1:7880) - REC: public_html/…/livekit-selfhost/recordings// altında MP4 (Egress .env ile aynı kök) ================================================================================ Not: AppConfig API kökünü host’a göre seçer; LiveKit adresi sunucudan (live_stream_token) döner — Flutter tarafında ayrı domain ayarı gerekmez. --- net::ERR_CERT_AUTHORITY_INVALID (wss / https LiveKit) --- Tarayıcı TLS’i güvenilir görmüyor; Flutter/PHP ile kodla düzeltilemez. 1) Nginx’te fullchain.pem kullanın (yalnızca cert.pem değil). 2) openssl s_client -connect novazeka.com.tr:443 -servername novazeka.com.tr Çıktıda konu (subject) Let’s Encrypt / novazeka.com.tr olmalı. 3) Cloudflare "Full (strict)" ise origin’de geçerli sertifika şart. 4) Genel DNS: dig +short novazeka.com.tr @8.8.8.8 → VPS IP görünmeli. Yerel modem (192.168.x) sertifikası görürseniz /etc/hosts veya DNS’i kontrol edin. --- "Failed to fetch" / https://novazeka.com.tr/rtc/validate --- 1) nginx-livekit-novazeka-root.snippet.conf içindeki large_client_header_buffers yüklü mü 2) curl -sS http://127.0.0.1:7880/ | head — LiveKit dinliyor mu 3) curl -sS -o /dev/null -w "%{http_code}" https://novazeka.com.tr/rtc/validate 4) Cloudflare: WebSockets açık; gerekirse ilgili host DNS-only --- "Failed to fetch" / https://novazeka.com.tr/novazeka/livekit/rtc/validate (C2) --- 1) apache-livekit-novazeka-prefix.conf.example gerçekten 443 vhost’a eklendi mi 2) curl -sS -o /dev/null -w "%{http_code}" https://novazeka.com.tr/novazeka/livekit/rtc/validate 3) Cloudflare: /novazeka/livekit/* için cache/WAF kuralı yok mu ================================================================================ G) TEK STACK — Aynı VPS’te birden fazla LiveKit / egress / redis (SORUN ÇIKTIRIR) ================================================================================ Belirti: ListEgress hep EGRESS_STARTING; StopEgress 408/deadline_exceeded; worker logunda egress_active ama API farklı; birden fazla livekit-server veya egress konteyneri. Hedef mimari: - 1× redis (127.0.0.1:6379) — livekit.yaml ve egress.yaml aynı address - 1× livekit-server — tek konteyner veya tek süreç, 7880 - 1× egress — ya docker compose ya da bash egress_run_standalone.sh (ikisini birden çalıştırmayın) Kontrol: docker ps -a --format '{{.Names}}\t{{.Image}}' | grep -iE 'livekit|egress|redis' Temizlik (bakım penceresinde; hangi LiveKit üretimde ise onu BIRAKIN): - Fazla egress: docker stop livekit-dev-egress-1 … ; sonra tek egress başlatın - Fazla livekit: Nginx/Apache hangi 127.0.0.1:7880’a gidiyorsa o konteyner kalsın; diğeri durdurulur - Zombi redis (livekit-redis_zombie_*): kullanılmıyorsa docker rm Repoda: livekit-selfhost/STACK_TEK_SUNUCU.txt ve egress_stack_audit.sh (önerilen komutları listeler). Nginx /twirp için proxy_read_timeout 600 sn (snippet güncel); Apache için ProxyTimeout 300. PHP StopEgress curl 180 sn (livekit_api_helper livekit_twirp_post). ================================================================================