A self-hosted, single-container live stream server. Accepts RTMP and WebRTC (WHIP) input, publishes as WebRTC (WHEP) and HLS. Zero configuration beyond your public IP.
Built on SRS v5 with an English UI, cloud auto-detection, and production-ready defaults.
- Docker (or Docker Compose)
- Ports 1935, 8080, 1985 (TCP) and 8000 (UDP+TCP) open on your firewall (for remote access)
- ~160MB disk for the Docker image
- ~20MB RAM at idle; scales with concurrent viewers
Runs on any platform Docker supports: Linux, macOS, Windows, ARM, x86_64.
┌──────────────────────┐
OBS / FFmpeg / Browser │ Docker WebRTC Server│ ──▶ WebRTC ── Browser
(RTMP or WHIP) └──────────────────────┘ ──▶ HLS ── Browser / VLC
Ingest (publish a stream):
- RTMP on port
1935— use OBS, FFmpeg, or any RTMP encoder - WebRTC via WHIP on port
1985— publish from a browser or OBS 30.2+
Playback (watch a stream):
- WebRTC via WHEP on port
1985— low latency in any modern browser - HLS on port
8080— broad compatibility, ~4-6s latency
Both directions work simultaneously. An RTMP stream from OBS is instantly available over WebRTC, and a WebRTC stream published via WHIP is available over RTMP/HLS.
| Port | Protocol | Purpose |
|---|---|---|
| 1935 | TCP | RTMP ingest |
| 8080 | TCP | HLS playback, built-in web player |
| 1985 | TCP | HTTP API, WHIP ingest, WHEP playback |
| 8000 | UDP+TCP | WebRTC media (ICE/SRTP) |
For testing on your own machine, no public IP needed:
docker run -d --name srs \
-p 1935:1935 \
-p 8080:8080 \
-p 1985:1985 \
-p 8000:8000/udp \
-p 8000:8000/tcp \
llewroberts/docker-webrtc-serverOr with Compose:
git clone https://github.com/L13w/docker-webrtc-server.git
cd docker-webrtc-server
docker compose up -dThen open http://localhost:8080 and publish to rtmp://localhost/live/stream1.
To allow viewers outside your network, set CANDIDATE_IP to your server's public IP:
docker run -d --name srs \
-p 1935:1935 \
-p 8080:8080 \
-p 1985:1985 \
-p 8000:8000/udp \
-p 8000:8000/tcp \
-e CANDIDATE_IP=YOUR_SERVER_IP \
llewroberts/docker-webrtc-serverOr with Compose:
git clone https://github.com/L13w/docker-webrtc-server.git
cd docker-webrtc-server
export CANDIDATE_IP=YOUR_SERVER_IP
docker compose up -dcurl http://localhost:1985/api/v1/versionsVisit http://YOUR_IP:8080 in a browser to access the console and test players.
On Azure, AWS, or GCP, you can skip setting CANDIDATE_IP and use auto-detection instead:
AUTO_DETECT_IP=true docker compose up -dThe entrypoint will query the cloud metadata service to find your public IP automatically.
- Open OBS Settings > Stream
- Set:
- Service: Custom
- Server:
rtmp://YOUR_SERVER_IP/live - Stream Key:
stream1(or any name you choose)
- Click Start Streaming
Your stream is now available at:
- WebRTC:
http://YOUR_SERVER_IP:1985/rtc/v1/whep/?app=live&stream=stream1 - HLS:
http://YOUR_SERVER_IP:8080/live/stream1.m3u8 - Built-in player:
http://YOUR_SERVER_IP:8080/players/rtc_player.html?stream=stream1
OBS 30.2 and later support WHIP output natively:
- Open OBS Settings > Stream
- Set:
- Service: WHIP
- Server:
http://YOUR_SERVER_IP:1985/rtc/v1/whip/?app=live&stream=stream1 - Bearer Token: (leave empty)
- Click Start Streaming
WHIP streaming gives you lower publish latency compared to RTMP but requires OBS 30.2+.
# Stream a video file via RTMP
ffmpeg -re -i video.mp4 -c copy -f flv rtmp://YOUR_SERVER_IP/live/stream1
# Stream a test pattern
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
-f lavfi -i sine=frequency=440:sample_rate=44100 \
-c:v libx264 -preset ultrafast -tune zerolatency \
-c:a aac -b:a 128k \
-f flv rtmp://YOUR_SERVER_IP/live/stream1Use the WHEP endpoint with any WHEP-compatible player:
http://YOUR_SERVER_IP:1985/rtc/v1/whep/?app=live&stream=stream1
Or use the built-in player:
http://YOUR_SERVER_IP:8080/players/rtc_player.html?stream=stream1
http://YOUR_SERVER_IP:8080/live/stream1.m3u8
Works with VLC, Safari, or any HLS player (hls.js, Video.js, etc.).
The server provides an HTTP API on port 1985:
| Endpoint | Description |
|---|---|
GET /api/v1/versions |
Server version |
GET /api/v1/summaries |
Server summary and health |
GET /api/v1/streams |
Active streams |
GET /api/v1/clients |
Connected clients |
POST /rtc/v1/whip/?app=live&stream=NAME |
WHIP publish endpoint |
POST /rtc/v1/whep/?app=live&stream=NAME |
WHEP playback endpoint |
Full API docs: SRS HTTP API
The server config is at srs.conf. Key settings:
rtmp_to_rtc on— RTMP streams are automatically available as WebRTCrtc_to_rtmp on— WebRTC streams are automatically available as RTMP/HLSgop_cache off— Disabled for lower WebRTC latency (no buffered GOP on connect)- HLS: 2-second fragments, 10-second window
To customize, edit srs.conf and rebuild:
docker compose build && docker compose up -dEnsure these ports are open on your server:
# Example for ufw
sudo ufw allow 1935/tcp # RTMP
sudo ufw allow 8080/tcp # HLS
sudo ufw allow 1985/tcp # API / WHIP / WHEP
sudo ufw allow 8000/udp # WebRTC media (UDP)
sudo ufw allow 8000/tcp # WebRTC media (TCP fallback)On cloud providers, update your security group / NSG to allow these ports.
This runs SRS v5, a widely-used open-source media server written in C++. SRS handles all protocol translation internally — there are no additional services, proxies, or dependencies. One container does everything.
SRS is licensed under MIT. This Docker configuration is also MIT licensed.