The fastest way to deploy Slyber SFU Server on any Linux server or local developer machine is to run the official container from the GitHub Container Registry. The prebuilt ghcr.io/slyber-app/slyber-sfu-server:latest image is automatically built for linux/amd64 and linux/arm64 CPU architectures on lightweight Alpine 3.20. Inside the image is the static binary /usr/local/bin/slyber_sfu, verified against the SHA256SUMS checksum. If you prefer installing directly on the host operating system without containers, go to Binary Installation and systemd Service Setup.
Quick One-Command Launch via Docker CLI
You do not need to clone the repository, install the Go compiler, or write configuration files manually. Copy and run the following command in your terminal. It pulls the latest image, automatically detects your server's external IP address, generates three isolated cryptographic keys, starts the container in the background, and immediately runs built-in node self-diagnostics.
docker pull ghcr.io/slyber-app/slyber-sfu-server:latest
docker rm -f slyber-sfu-server 2>/dev/null || true
PUBLIC_IP=$(curl -fsSL4 --max-time 2 api.ipify.org 2>/dev/null || echo 127.0.0.1)
JWT_SECRET=$(head -c 24 /dev/urandom | od -An -tx1 | tr -d ' \n')
NODE_SECRET=$(head -c 24 /dev/urandom | od -An -tx1 | tr -d ' \n')
docker run -d \
--name slyber-sfu-server \
--restart unless-stopped \
--network host \
-e SFU_ENV="production" \
-e PUBLIC_IP="${PUBLIC_IP}" \
-e SFU_UDP_PORT="4443" \
-e SFU_TCP_PORT="4443" \
-e SFU_HTTP_PORT="8090" \
-e AUTH_MODE="jwt" \
-e JWT_SECRET="${JWT_SECRET}" \
-e NODE_SECRET="${NODE_SECRET}" \
ghcr.io/slyber-app/slyber-sfu-server:latest && \
sleep 1 && \
docker exec slyber-sfu-server slyber_sfu doctor && \
echo "Public IP : ${PUBLIC_IP}" && \
echo "JWT Secret : ${JWT_SECRET}" && \
echo "Node Secret: ${NODE_SECRET}" && \
echo "Test Token : $(curl -fsS -H "X-Slyber-Node-Secret: ${NODE_SECRET}" "http://127.0.0.1:8090/auth/token?room=test-room&user=user-1")"
Immediately after running the command, a green report from the slyber_sfu doctor utility and the generated secret keys will appear in the console, ready to copy into your backend configuration or the Slyber Inspector visual test bench.
How the Container Works Internally and Why It Is Secure
The official Docker image is engineered to production security standards.
- Non-root execution. An isolated system group and user
slyber_sfuwithUID 10001and interactive login disabled (/sbin/nologin) are created inside the container. The media server process never runs asroot. - Binding privileged ports. During the image build, the binary
/usr/local/bin/slyber_sfuis granted the targeted kernel capabilitycap_net_bind_service=+epviasetcap. This allows the unprivileged user to bind system ports below 1024 if needed (such as port443to traverse strict corporate proxies). - Single port for media traffic. Because the Pion WebRTC stack multiplexes all connections over a single port
4443, you only need to expose three ports in Docker (4443/udp,4443/tcp, and8090/tcp) without creating heavy iptables rules for tens of thousands of ports. On high-load Linux servers, you can also pass--network hostinstead of-pflags for direct host NIC access.
Launch Examples for Different Authentication Modes
Depending on your project's architecture, you can launch the container in one of three client token verification modes (for a detailed cryptographic breakdown, see Authentication and SFrame E2EE End-to-End Encryption).
1. Running in Secret or JWT Mode and Issuing Your First Token
This scenario is ideal for quick verification on a local machine or test server. We start the container and immediately request a ready-to-use token from the built-in /auth/token generator for user erkin in room test-room.
docker run -d \
--name slyber_sfu_secret \
-p 4443:4443/udp -p 4443:4443/tcp -p 8090:8090/tcp \
-e PUBLIC_IP="127.0.0.1" \
-e REALM="sfu.local" \
-e SFU_UDP_PORT="4443" \
-e SFU_TCP_PORT="4443" \
-e SFU_HTTP_PORT="8090" \
-e AUTH_MODE="secret" \
-e TURN_SECRET="my-custom-sfu-turn-secret-2026" \
-e JWT_SECRET="my-custom-sfu-jwt-secret-2026" \
-e NODE_SECRET="my-custom-sfu-node-secret-2026" \
ghcr.io/slyber-app/slyber-sfu-server:latest
# Issue ready-to-use tokens via the administrative endpoint
curl -s -H "X-Slyber-Node-Secret: my-custom-sfu-node-secret-2026" \
"http://127.0.0.1:8090/auth/token?room=test-room&user=erkin"
2. Running with Redis on a Shared Docker Network
If you want to manage active sessions via a Redis database and immediately revoke participant access mid-call, create a shared Docker network and launch both containers using the commands below.
# 1. Create an isolated Docker network and start Redis
docker network create slyber_sfu_net
docker run -d --name slyber_sfu_redis --network slyber_sfu_net redis:alpine
# 2. Store a test session with a 3600-second TTL
docker exec slyber_sfu_redis redis-cli SET "slyber:session:tok_777" "erkin" EX 3600
# 3. Start Slyber SFU Server in redis mode
docker run -d \
--name slyber-sfu-server \
--network slyber_sfu_net \
-p 4443:4443/udp -p 4443:4443/tcp -p 8090:8090/tcp \
-e PUBLIC_IP="127.0.0.1" \
-e REALM="sfu.local" \
-e SFU_UDP_PORT="4443" \
-e SFU_TCP_PORT="4443" \
-e SFU_HTTP_PORT="8090" \
-e AUTH_MODE="redis" \
-e REDIS_ADDR="slyber_sfu_redis:6379" \
-e NODE_SECRET="my-custom-sfu-node-secret-2026" \
ghcr.io/slyber-app/slyber-sfu-server:latest
# 4. Verify that the SFU server can reach Redis and passes diagnostics
docker exec slyber-sfu-server slyber_sfu doctor
Container Management, Diagnostics, and Updates
Use standard Docker CLI commands for day-to-day maintenance of the running container.
# Check the binary version inside the image
docker run --rm ghcr.io/slyber-app/slyber-sfu-server:latest --version
# Run full self-diagnostics inside the running container
docker exec slyber-sfu-server slyber_sfu doctor
# View startup logs and cumulative packet statistics
docker logs -f slyber-sfu-server
# Check the server HTTP health endpoint
curl -i http://127.0.0.1:8090/healthz
Alternative Launch via Docker Compose
If your infrastructure manages services declaratively, you can use the ready-made docker-compose.yml template with host networking and automatic log rotation.
services:
slyber-sfu:
image: ghcr.io/slyber-app/slyber-sfu-server:latest
container_name: slyber-sfu-server
restart: unless-stopped
network_mode: host
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
ulimits:
nofile:
soft: 65535
hard: 65535
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
environment:
SFU_ENV: "${SFU_ENV:-production}"
SFU_NODE_ID: "${SFU_NODE_ID:-slyber-sfu-01}"
PUBLIC_IP: "${PUBLIC_IP:?Set PUBLIC_IP in .env}"
REALM: "${REALM:-slyber.com}"
DEFAULT_ROOM_PROFILE: "${DEFAULT_ROOM_PROFILE:-conference}"
SFU_UDP_PORT: "${SFU_UDP_PORT:-4443}"
SFU_TCP_PORT: "${SFU_TCP_PORT:-4443}"
SFU_HTTP_PORT: "${SFU_HTTP_PORT:-8090}"
ENABLE_ICE_TCP: "${ENABLE_ICE_TCP:-true}"
SOCKET_BUFFER_BYTES: "${SOCKET_BUFFER_BYTES:-8388608}"
EXTERNAL_TURN_URLS: "${EXTERNAL_TURN_URLS:-}"
AUTH_MODE: "${AUTH_MODE:-jwt}"
JWT_SECRET: "${JWT_SECRET:?Set JWT_SECRET (min 24 chars) in .env}"
NODE_SECRET: "${NODE_SECRET:?Set NODE_SECRET (min 24 chars) in .env}"
TURN_SECRET: "${TURN_SECRET:-}"
ALLOWED_ORIGINS: "${ALLOWED_ORIGINS:-https://slyber.com}"
CREDENTIAL_TTL_SEC: "${CREDENTIAL_TTL_SEC:-3600}"
REQUIRE_E2EE: "${REQUIRE_E2EE:-false}"
REDIS_ADDR: "${REDIS_ADDR:-127.0.0.1:6379}"
MAX_KBPS_PER_TRACK: "${MAX_KBPS_PER_TRACK:-3500}"
MAX_KBPS_PER_SESSION: "${MAX_KBPS_PER_SESSION:-10000}"
ENABLE_SIMULCAST: "${ENABLE_SIMULCAST:-true}"
ENABLE_SVC: "${ENABLE_SVC:-true}"
VIDEO_CODECS: "${VIDEO_CODECS:-VP9,AV1,H264,VP8}"
NACK_BUFFER_SIZE: "${NACK_BUFFER_SIZE:-512}"
LAST_N_VIDEO_LIMIT: "${LAST_N_VIDEO_LIMIT:-16}"
DYNACAST_ENABLED: "${DYNACAST_ENABLED:-true}"
ENABLE_WHIP_WHEP: "${ENABLE_WHIP_WHEP:-true}"
ENABLE_MOQ_RELAY: "${ENABLE_MOQ_RELAY:-false}"
ENABLE_AI_GATEWAY: "${ENABLE_AI_GATEWAY:-true}"
ENABLE_CASCADE_PIPE: "${ENABLE_CASCADE_PIPE:-true}"
ENABLE_INSPECTOR: "${ENABLE_INSPECTOR:-true}"
Complete Environment Variables Reference
Network Stack and Node Identification
SFU_ENVsets the server operating mode (productionenforces key length validation and a routable IP address, whiledevelopmentallows local startup without keys).SFU_NODE_IDsets the unique server name in Prometheus metrics and cascading headers (default:slyber-sfu-01).PUBLIC_IPsets the host's public IPv4 address that Pion WebRTC advertises in ICE candidates for browser connections (supportsautofor automatic detection).REALMsets the server's authentication domain zone (default:slyber.com).DEFAULT_ROOM_PROFILEsets the default profile for newly created rooms (conference,roulette_1v1,broadcast,gaming, orai_voice).SFU_UDP_PORTandSFU_TCP_PORTset the unified port for receiving WebRTC media traffic over UDP and RFC 4571 TCP (default:4443).SFU_HTTP_PORTsets the TCP port for the WebSocket signaling gateway, WHIP/WHEP, and telemetry (default:8090).ENABLE_ICE_TCPenables or disables media transport over TCP (default:true).ALLOW_PORT_FALLBACKallows the server to automatically bind the next available port on a port conflict (default:false).SOCKET_BUFFER_BYTESsets the OS UDP socket read and write buffer size in bytes (default:8388608bytes, i.e., 8 MB).EXTERNAL_TURN_URLSaccepts a comma-separated list of external TURN servers to automatically issue temporary credentials to clients upon joining a room.
Security, Keys, and Redis Connection
AUTH_MODEselects the client token verification mode betweenjwt,redis, andsecret.JWT_SECRETsets the HMAC-SHA256 signing key for client tokens injwtmode (minimum 24 characters in production).TURN_SECRETsets the shared HMAC-SHA1 secret key forsecretmode and generating passwords for external servers listed inEXTERNAL_TURN_URLS.NODE_SECRETsets an isolated administrative key for accessing the/ai/ws,/cascade/,/auth/token, and/inspector/statsgateways via theX-Slyber-Node-Secretheader.ALLOWED_ORIGINSsets a comma-separated list of allowed domains for validating theOriginheader in WebSocket and CORS requests.ALLOW_INTERNAL_CASCADEallows internal IP addresses (RFC 1918 and loopback) in inter-server cascading (default:falseto protect against SSRF attacks).CREDENTIAL_TTL_SECsets the lifetime of issued temporary tokens in seconds (default:3600).REQUIRE_E2EEenforces SFrame end-to-end encryption across all rooms on the node (default:false).REDIS_ADDR,REDIS_USERNAME,REDIS_PASSWORD, andREDIS_DBconfigure connection parameters for the Redis server when usingAUTH_MODE=redis.
Media Quality Control (QoS) and Gateways
MAX_KBPS_PER_TRACKandMAX_KBPS_PER_SESSIONlimit the maximum incoming bitrate of a single media track and an entire participant session in kilobits per second (defaults:3500and10000).ENABLE_SIMULCASTandENABLE_SVCcontrol support for multi-layer Simulcast video and scalable codec SVC filtering (default:true).VIDEO_CODECSdefines a comma-separated list of enabled video codecs (default:VP9,AV1,H264,VP8).NACK_BUFFER_SIZEsets the packet ring buffer size per spatial layer for handling NACK retransmission requests (default:512).LAST_N_VIDEO_LIMITsets the maximum number of simultaneously active video cameras in a conference room (default:16).DYNACAST_ENABLEDenables automatic quality layer switching based on bandwidth estimation (BWE) feedback (default:true).ENABLE_WHIP_WHEP,ENABLE_MOQ_RELAY,ENABLE_AI_GATEWAY,ENABLE_CASCADE_PIPE, andENABLE_INSPECTORenable or disable the respective server gateways (how each gateway works is covered in detail in WHIP and WHEP Gateways, AI Voice Pipeline, and Telemetry).