Flarum Social eklentisinin sesli odaları ve ekran paylaşımı LiveKit üzerine kurulu. LiveKit’i kurmak tek başına yeterli değil; doğru TLS sertifikası, WebSocket proxy’si, UDP portları, TURN yapılandırması ve Cloudflare tarafındaki DNS/cache kuralları birlikte doğru olmalı. Aksi halde sesli odaya girersiniz ama ses gelmez, ekran paylaşımı açılmaz veya “invalid API key” hatası alırsınız.
Bu rehber, Flarum Social’i üretim ortamında LiveKit ile çalıştırmak isteyenler için hazırlandı. Ubuntu tabanlı bir VPS, Docker, Nginx (veya Caddy), Cloudflare ve Flarum 2.0 varsayılıyor. Anlatılan alan adlarını kendi alan adlarınızla değiştirmeyi unutmayın: forum.example.com, livekit.example.com ve turn.example.com.

1. Mimariyi doğru kurmak
Flarum Social tarayıcıda çalışır. Sesli odaya katılan kullanıcı önce Flarum’a giriş yapar, ardından LiveKit’ten bir erişim token’ı alır. Tarayıcı LiveKit’e WebSocket (WSS) ile bağlanır; ses, video ve ekran paylaşımı ise WebRTC’nin UDP/TCP taşıma katmanı üzerinden doğrudan LiveKit sunucusuna akar.
Bu yüzden iki ayrı yol vardır:
- Sinyal yolu: Tarayıcı →
wss://livekit.example.com→ Nginx/Caddy → LiveKit:7880. - Medya yolu: Tarayıcı → LiveKit’in genel IP’si üzerinden UDP
50000-60000veya TCP7881. Bu trafik Cloudflare proxy’sinden geçmez.
Cloudflare’i yalnızca ana Flarum sitesi için kullanmak en sade ve en güvenilir yöntem. LiveKit ve TURN alt alan adlarını DNS only (gri bulut) bıraktığınızda sertifika yönetimi, WebSocket ve TURN/TLS tarafında sürprizlerle uğraşmazsınız. Cloudflare proxy’sini LiveKit için kullanmak mümkün ama aşağıda anlatılan ek koşullara bağlı.
2. Gereksinimler ve portlar
Küçük ve orta ölçekli bir topluluk için başlangıç olarak 2 vCPU, 2-4 GB RAM ve genel IP’li bir VPS yeterli olabilir. LiveKit’te performansın ana belirleyicisi CPU ve özellikle bant genişliğidir; sesli odalarda katılımcı sayısı ve ekran paylaşımı arttıkça kaynak ihtiyacı da artar. Üretimde sabit bir LiveKit sürümü kullanmak ve güncellemeleri kontrollü yapmak daha güvenlidir.
| Port | Protokol | Amaç |
|---|---|---|
| 80 | TCP | Let’s Encrypt / Caddy sertifika doğrulaması |
| 443 | TCP | WSS (LiveKit sinyal) ve ana site HTTPS |
| 7880 | TCP | LiveKit HTTP/WebSocket (dışarı açılmaz, proxy arkasında) |
| 7881 | TCP | UDP çalışmayan ağlar için WebRTC TCP yedeği |
| 50000-60000 | UDP | WebRTC ses/video/ekran paylaşımı |
| 3478 | UDP | TURN/UDP (kısıtlı ağlar için) |
| 5349 | TCP | TURN/TLS (manuel kurulumda; 443 kullanımı için aşağıya bakın) |
Bulut sağlayıcınızın güvenlik duvarı (Security Group / Firewall) ile sunucudaki UFW/nftables kurallarının ikisinde de bu portları açmanız gerekir. Özellikle UDP 50000-60000 aralığını atlamak, “bağlandı ama ses yok” sorununun en yaygın nedenidir.
3. DNS ve Cloudflare hazırlığı
Önce DNS kayıtlarını netleştirin:
forum.example.com→ sunucu IP’si, Cloudflare’de Proxied (turuncu bulut) kalabilir.livekit.example.com→ sunucu IP’si, DNS only (gri bulut).turn.example.com→ sunucu IP’si, DNS only (gri bulut).
Neden DNS only? LiveKit’in önünde TLS sonlandıran bir Nginx/Caddy olacak. Cloudflare proxy’si açıkken sertifika doğrulaması, WebSocket yönlendirmesi ve özellikle TURN/TLS 443 portu çakışabilir. Ayrıca WebRTC medyası UDP üzerinden gider ve Cloudflare’in standart proxy’si bu trafiği taşımaz. LiveKit, ICE adaylarında sunucunun genel IP’sini duyurduğu için medya yine doğrudan sunucuya gider; ancak DNS-only yapılandırması hem daha anlaşılır hem de daha az kırılgandır.
Ana Flarum sitesi için Cloudflare’de:
- SSL/TLS → Overview: Full (strict) kullanın. Flexible mod, Flarum oturumları ve API için güvenli değildir.
- Always Use HTTPS ve uygun bir HSTS politikası açın.
- WebSockets açık olsun (Cloudflare’de genellikle varsayılan olarak açıktır).
- Rocket Loader‘ı Flarum Social için kapatın. Mithril tabanlı SPA yönlendirmesini ve dinamik script yüklemelerini bozabilir. En azından
/social*ve/admin*için devre dışı bırakın. - Under Attack modunu forum açıkken kullanmayın; WebSocket ve API isteklerini kesebilir.
Cache tarafında şu kural seti işinizi görür:
- Bypass cache:
/social*,/api/*,/admin*,/login*,/logout*. - Cache eligible:
/assets/*, tema görselleri, fontlar ve sürümlenmiş statik dosyalar. - HTML’yi genel olarak edge’de önbelleğe almayın; Flarum Social dinamik bir uygulamadır. HTML cache’i açarsanız yeni gönderiler ve oturum durumu gecikebilir.
Cloudflare WAF kullanıyorsanız /api/* ve /social* için “Managed Challenge” tetikleyen kuralları gözden geçirin. Meşru AJAX istekleri challenge’a takılırsa arayüz boş görünebilir. LiveKit alt alan adını DNS-only bıraktığınızda WAF zaten devre dışı kalır.
4. Yöntem A: LiveKit’in resmî üretim generator’ı (önerilen)
LiveKit, Docker Compose + Caddy + Redis + TURN/TLS içeren üretim yapılandırmasını otomatik üreten bir araç sunuyor. Özellikle TURN/TLS’in 443 portunda çalışması ve sertifikaların otomatik alınması gerekiyorsa en pratik yol bu.
Generator’ı kendi bilgisayarınızda veya sunucuda çalıştırabilirsiniz. Çıktı dosyalarını sunucuya taşıyacaksınız:
docker pull livekit/generate
docker run --rm -it -v$PWD:/output livekit/generate
Araç sizden ana LiveKit alan adını, TURN alan adını ve e-posta adresinizi ister. Sonuçta şuna benzer bir klasör oluşur:
livekit.example.com/
├── caddy.yaml
├── docker-compose.yaml
├── livekit.yaml
├── redis.conf
├── init_script.sh
└── cloud-init.yaml (sağlayıcıya göre)
Sunucuya kurulum için iki seçenek var:
- Cloud-init: VPS sağlayıcınız destekliyorsa
cloud-init.yamliçeriğini “User data” alanına yapıştırın. Sunucu açılırken Docker, LiveKit ve systemd servisi otomatik kurulur. - Init script: Dosyayı sunucuya kopyalayıp
sudo ./init_script.shçalıştırın. Script Docker’ı, Compose’u ve/opt/livekitaltındaki yapılandırmayı hazırlar;livekit-dockersystemd servisini oluşturur.
Kurulumdan sonra servisi kontrol edin:
sudo systemctl status livekit-docker
cd /opt/livekit
sudo docker compose logs -f
Güvenlik duvarında 80/tcp, 443/tcp, 7881/tcp, 3478/udp ve 50000-60000/udp portlarını açın. Caddy sertifikayı otomatik alır; loglarda “certificate obtained successfully” benzeri bir satır görmelisiniz. curl -I http://livekit.example.com komutu bağlantıyı hemen kapatmıyorsa ve bir HTTP yanıtı dönüyorsa (genellikle 404) TLS/proxy tarafı çalışıyor demektir.
Not: Generator’ın ürettiği livekit.yaml içinde API anahtarı ve secret bulunur. Bu dosyayı Git’e eklemeyin, yedeklerini şifreli tutun ve izinlerini 600 yapın. Aynı secret’ı Flarum ACP’ye gireceksiniz.
5. Yöntem B: Docker Compose + Nginx + Certbot (manuel kurulum)
Daha fazla kontrol isteyenler için tek sunuculu, Redis’siz bir kurulum yeterli olabilir. Çoklu LiveKit düğümü kuracaksanız Redis eklemeniz gerekir; tek düğümde LiveKit kendi durumunu bellekte tutar.
5.1. Docker ve dizin hazırlığı
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
sudo mkdir -p /opt/livekit
cd /opt/livekit
API anahtarı ve secret için rastgele değerler üretin. İki ayrı komut çalıştırın; ilk çıktıyı anahtar, ikincisini secret olarak kullanın:
openssl rand -hex 16
openssl rand -hex 32
5.2. LiveKit yapılandırması
/opt/livekit/livekit.yaml dosyasını oluşturun:
port: 7880
log_level: info
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
keys:
BURAYA_API_KEY: BURAYA_API_SECRET
turn:
enabled: true
domain: turn.example.com
tls_port: 5349
udp_port: 3478
cert_file: /etc/letsencrypt/live/livekit.example.com/fullchain.pem
key_file: /etc/letsencrypt/live/livekit.example.com/privkey.pem
use_external_ip: true, sunucunun genel IP’sini STUN ile bulmaya çalışır. Bulut NAT’ı nedeniyle yanlış IP duyurulursa use_external_ip: false yapıp node_ip: SUNUCU_GENEL_IP ekleyin. turn.domain alanı sertifikadaki alan adıyla birebir eşleşmeli.
5.3. Docker Compose
WebRTC’nin geniş UDP port aralığı için host network kullanmak en sorunsuz yöntemdir. /opt/livekit/docker-compose.yaml:
services:
livekit:
image: livekit/livekit-server:latest
command: --config /etc/livekit.yaml
restart: unless-stopped
network_mode: host
volumes:
- ./livekit.yaml:/etc/livekit.yaml:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
Üretimde latest yerine test ettiğiniz belirli bir sürümü sabitleyin. Örneğin livekit/livekit-server:v1.x.y gibi; buradaki sürüm numarasını LiveKit Releases sayfasındaki güncel kararlı sürümle değiştirin.
5.4. Sertifika ve Nginx
LiveKit ve TURN için tek bir sertifika kullanabilirsiniz. Certbot’un standalone modu 80 portunu kullanır; işlem sırasında Nginx’i geçici olarak durdurun:
sudo apt update
sudo apt install -y certbot
sudo systemctl stop nginx
sudo certbot certonly --standalone
-d livekit.example.com
-d turn.example.com
sudo systemctl start nginx
Nginx’te WebSocket yükseltmesini destekleyen bir sunucu bloğu oluşturun. /etc/nginx/conf.d/livekit.conf:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name livekit.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name livekit.example.com;
ssl_certificate /etc/letsencrypt/live/livekit.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/livekit.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
}
Yapılandırmayı test edip yeniden yükleyin:
sudo nginx -t
sudo systemctl reload nginx
5.5. Güvenlik duvarı ve başlatma
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 7881/tcp
sudo ufw allow 50000:60000/udp
sudo ufw allow 3478/udp
sudo ufw allow 5349/tcp
sudo ufw enable
cd /opt/livekit
sudo docker compose up -d
sudo docker compose logs -f
UFW uyarısı: ufw enable komutundan önce SSH portunuzun (genellikle 22/tcp) açık olduğundan emin olun; aksi halde sunucuya erişiminizi kaybedebilirsiniz.
Loglarda starting LiveKit server, RTCEngine started ve TURN ile ilgili satırları görmelisiniz. curl -I https://livekit.example.com bağlantıyı asılı bırakmamalı; 404 veya benzeri bir HTTP yanıtı normaldir. LiveKit’in kök dizinde bir web sayfası yoktur.
TURN/TLS ve 443 notu
Yukarıdaki manuel kurulumda TURN/TLS 5349 portunda. Bazı kurumsal ağlar yalnızca 443’e izin verir. TURN/TLS’i 443’te sunmak istiyorsanız aynı IP’de Nginx’in 443’ü ile çakışırsınız. Çözüm olarak LiveKit’in resmî generator’ını (Caddy tabanlı yapılandırması bu çakışmayı yönetir) veya HAProxy/nginx stream gibi bir layer-4 SNI proxy kullanın. Basit kurulumda 5349 yeterlidir; TURN/UDP 3478 de kısıtlı ağlarda yardımcı olur.
6. Flarum Social ACP ayarları
LiveKit ayağa kalktıktan sonra Flarum yönetim panelinde Flarum Social → Voice bölümüne gidin:
- LiveKit URL:
wss://livekit.example.com(üretimde mutlakawss://;ws://yalnızca localhost geliştirme içindir). - API Key:
livekit.yamliçindeki anahtar. - API Secret: Aynı dosyadaki secret. Bu değer yalnızca sunucu tarafında saklanır ve tarayıcı paketine dahil edilmez.
- Default / maximum room capacity: Oda başına katılımcı sınırları.
- Push to talk / PTT key: Global varsayılanlar; kullanıcılar kendi ses ayarlarından değiştirebilir.
- Voice sounds: Discord tarzı katılma/ayrılma/susturma sesleri.
- Enable screen sharing: Ekran paylaşımını global olarak açar/kapatır. Oda bazında da ayrı anahtar vardır.
- Maximum simultaneous screen shares: Aynı anda kaç ekran paylaşımına izin verileceği.
- Automatically reconnect voice: Kısa ağ kesintilerinde otomatik yeniden bağlanma.
Ardından Yönetim → İzinler bölümünde social.shareScreen iznini ekran paylaşmasına izin vermek istediğiniz gruplara verin. Değişikliklerden sonra:
php flarum cache:clear
Ekran paylaşımı ve mikrofon erişimi tarayıcı tarafında güvenli kaynak (HTTPS) gerektirir. localhost geliştirme için istisnadır; üretimde düz HTTP üzerinden çalışmaz.
7. İki tarayıcıyla test
Kurulumu doğrulamanın en hızlı yolu iki farklı tarayıcıda iki farklı Flarum kullanıcısıyla aynı sesli odaya girmek:
/socialsayfasını açın ve bir sesli odaya katılın.- İkinci tarayıcıda farklı bir hesapla aynı odaya girin.
- Mikrofon iznini verin; iki tarafta da yeşil konuşma göstergesini kontrol edin.
- Bir tarafta Share screen seçeneğine tıklayın ve ekranı paylaşın.
- Diğer tarayıcıda paylaşımın görünmesini ve tam ekran açılmasını doğrulayın.
- Bir kullanıcıyı susturun, sesini kısın ve odadan çıkarın; katılımcı listesinin güncellendiğini görün.
Bu adımlar çalışıyorsa sinyal, medya ve TURN tarafı büyük ölçüde doğru demektir. Yalnızca mikrofon çalışmıyorsa tarayıcı izinlerine, yalnızca uzak kullanıcıda ses yoksa UDP portlarına ve NAT’a bakın.
8. Cloudflare’i LiveKit ile birlikte kullanmak (ileri seviye)
Ana siteyi Cloudflare arkasında tutup LiveKit’i ayrı bir alt alan adında proxy’lemek mümkündür, ancak dikkat edilmesi gereken noktalar var:
- WebSocket: Cloudflare proxy’si WSS bağlantısını taşıyabilir; Nginx’te
UpgradeveConnectionbaşlıklarının doğru geçtiğinden emin olun. - Medya: UDP
50000-60000ve TCP7881Cloudflare proxy’sinden geçmez. Bu portlar sunucuda açık olmalı ve LiveKit doğru genel IP’yi duyurmalı. - TURN/TLS: 443 portunu Cloudflare proxy’si ile paylaşamazsınız. TURN için ayrı ve DNS-only bir
turn.example.comkullanın veya TURN/TLS’i 5349’da sunun. - WAF: LiveKit’in
/rtcWebSocket handshake’ine managed challenge uygulanmamalı. Gerekirse bu yol için WAF skip kuralı oluşturun. - Zaman aşımları: Cloudflare ve Nginx tarafında WebSocket’in uzun süre açık kalmasına izin verin. LiveKit ping gönderir; yine de
proxy_read_timeoutdeğerini yüksek tutun.
Bu karmaşıklık gereksizse en temiz çözüm: ana site Cloudflare’de proxied, livekit.example.com ve turn.example.com DNS-only. Sertifikayı Nginx/Caddy yönetir, medya doğrudan sunucuya gider.
9. Sorun giderme
“Invalid API key” hatası
Bu hata Flarum’dan değil LiveKit’ten gelir. Tarayıcıya verilen token, LiveKit sunucusunun tanımadığı bir anahtar/secret ile imzalanmıştır. ACP’deki URL, API key ve secret’ın livekit.yaml ile birebir aynı olduğunu kontrol edin. devkey/secret veya testkey gibi geliştirme/örnek değerleri üretimde çalışmaz. Ses kullanmayacaksanız üç alanı da boş bırakın; Social “Voice is not configured” gösterir.
Mikrofon veya ekran paylaşımı açılmıyor
Sayfanın HTTPS ile açıldığından emin olun. Tarayıcı adres çubuğundaki mikrofon/kamera izinlerini kontrol edin. Ekran paylaşımı için social.shareScreen izni, global ekran paylaşımı anahtarı ve oda bazındaki anahtarın açık olması gerekir. Firefox/Safari’de ekran paylaşımı davranışı Chrome’dan farklı olabilir; testi Chrome/Edge ile yapın.
Odaya giriyor ama ses gelmiyor
Önce UDP 50000-60000 aralığının hem bulut güvenlik duvarında hem sunucuda açık olduğunu doğrulayın. LiveKit loglarında ICE/DTLS ile ilgili hatalara bakın. Sunucu NAT arkasındaysa use_external_ip: true çalışıyor mu kontrol edin; olmuyorsa node_ip ile genel IP’yi elle verin. Kısıtlı ağlarda TURN/TLS veya TURN/UDP’nin açık olduğundan emin olun.
WSS 502 / 504
Nginx LiveKit’e ulaşamıyor demektir. docker compose ps ve docker compose logs ile LiveKit’in çalıştığını kontrol edin. Nginx’te proxy_pass http://127.0.0.1:7880 doğru mu, Upgrade başlıkları geçiyor mu bakın. Cloudflare proxy’si kullanıyorsanız SSL modunun Full (strict) olduğundan emin olun.
Sertifika alınamıyor
Alan adının sunucu IP’sine çözüldüğünü (dig +short livekit.example.com) ve 80/443 portlarının dışarıdan erişilebilir olduğunu kontrol edin. Cloudflare’de kayıt proxied ise ACME HTTP-01 doğrulaması engellenebilir; LiveKit/TURN kayıtlarını DNS-only yapın. Caddy kullanıyorsanız loglarda sertifika edinme hatasını görürsünüz.
TURN çalışmıyor
turn.domain ile sertifika alan adının eşleştiğinden emin olun. TURN/TLS portunun (5349 veya 443) ve TURN/UDP 3478’in açık olduğunu kontrol edin. 443’ü Nginx ile paylaşmaya çalışıyorsanız çakışma kaçınılmazdır; ayrı DNS-only TURN alan adı veya layer-4 proxy kullanın.
Geçici odalar hemen kayboluyor
ACP’deki temporary_room_empty_seconds değerini artırın ve zamanlanmış görevin çalıştığından emin olun:
* * * * * cd /var/www/flarum && php flarum schedule:run
Medya yüklemeleri başarısız
PHP upload_max_filesize, post_max_size ve Flarum Social’in max_image_mb, max_video_mb, max_document_mb, user_quota_mb ayarlarını kontrol edin. S3 modu kullanıyorsanız Flysystem/S3 paketleri ve bucket kimlik bilgileri doğru olmalı.
10. Güvenlik kontrol listesi
- LiveKit API key/secret’i benzersiz ve uzun tutun; geliştirme değerlerini üretimde kullanmayın.
- Secret’ı Git’e, foruma veya istemci tarafına koymayın. Yalnızca sunucu ayarlarında saklayın.
- LiveKit’in
7880portunu dışarıya açmayın; yalnızca Nginx/Caddy’ye açık olsun. - Firewall’da yalnızca gerekli portları açın; UDP
50000-60000ve TCP7881medya için gerekli. - Üretimde LiveKit imaj sürümünü sabitleyin ve düzenli güncelleyin.
- Redis kullanıyorsanız parola ve özel ağ ile koruyun.
- TLS sertifikalarını otomatik yenileyin (Certbot timer veya Caddy).
- Cloudflare’de ana site için WAF ve rate limit kullanın; LiveKit/TURN’ü DNS-only bırakın.
- Ekran paylaşımı iznini yalnızca güvenilir gruplara verin.
- Flarum veritabanını ve medya dosyalarını düzenli yedekleyin; LiveKit tek düğümde durum tutmaz, yedeklenmesi gereken asıl veri Flarum’dadır.
11. Ölçekleme ve isteğe bağlı bileşenler
Birden fazla LiveKit düğümü kuracaksanız Redis’i ortak durum ve mesajlaşma için ekleyin; istemcileri bir yük dengeleyici arkasında toplayın. LiveKit API ve WebSocket katmanı yatay ölçeklenebilir, ancak medya trafiği her düğümün kendi UDP portlarına gider.
Centrifugo, Flarum Social’in metin kanalları ve doğrudan mesajlarında gerçek zamanlı teslimat için kullanılabilir. LiveKit ile aynı şey değildir; biri medya, diğeri mesajlaşma içindir. Centrifugo’yu kurduysanız ACP’deki Messages & realtime bölümüne WebSocket URL’sini, HTTP API URL’sini, API anahtarını ve HMAC secret’ını girin.
S3 uyumlu depolama, medya dosyalarını sunucu dışında tutmak için kullanılabilir. Flarum Social’in medya hattı S3 modunu destekler; bucket kimlik bilgilerini ve Flysystem paketlerini doğru yapılandırın.
Sonuç
Flarum Social’in sesli odaları, doğru kurulmuş bir LiveKit altyapısıyla Discord benzeri bir deneyim sunar. Kritik noktaları özetlersek: ana site Cloudflare arkasında kalabilir; LiveKit ve TURN DNS-only olmalı; WSS için Nginx/Caddy’de WebSocket yükseltmesi açık olmalı; UDP 50000-60000 ve TCP 7881 doğrudan erişilebilir olmalı; TURN/TLS kısıtlı ağlar için hazırlanmalı; ACP’deki URL, key ve secret LiveKit yapılandırmasıyla birebir eşleşmeli.
Bu adımları tamamladıktan sonra iki tarayıcıyla yapacağınız ses ve ekran paylaşımı testi, kurulumun sağlıklı olduğunu gösterecektir. Sorun yaşarsanız önce LiveKit loglarına, sonra Nginx loglarına, en son Cloudflare/DNS ayarlarına bakın.
- Flarum Social: github.com/cengizkemec/flarum-social
- Flarum Social dokümantasyonu: github.com/cengizkemec/flarum-social/tree/main/docs
- LiveKit self-hosting: docs.livekit.io/transport/self-hosting
- LiveKit portlar ve güvenlik duvarı: docs.livekit.io/transport/self-hosting/ports-firewall
- Cloudflare SSL/TLS: developers.cloudflare.com/ssl
