Create an simple Live Webcast with Nginx RTMP
Introduction
This blog demonstrates how to build a live streaming server using Nginx with RTMP module and Docker. Here are some things we should know:
- Accept live video streams from sources like OBS or ffmpeg via RTMP protocol
- Convert RTMP streams to HLS (HTTP Live Streaming) format for browser playback
- Set up a complete streaming infrastructure using Docker Compose
- Test your setup with a sample video player
By the end, you'll have a working live streaming server that can receive streams on port 1935 and deliver them to viewers via HTTP on port 8181.
Concept
This guide shows a minimal, practical setup to accept an RTMP stream (from OBS or ffmpeg), produce HLS segments with Nginx RTMP, and serve them over HTTP for browser playback.
In the final setup used for this post:
- RTMP ingest endpoint:
rtmp://localhost/live/stream-test - HLS playback URL:
http://localhost:8181/hls/stream-test.m3u8
How it flows
Project layout
Files in this repo used for the demo:
Docker/
rtmp.Dockerfile
docker-compose.yml
nginx.conf
player.html
videos/
All commands below are meant to be run from the repository root.
Docker Compose services (summary)
This example uses three services:
nginx-rtmp: a Debian-based container with nginx + RTMP module to accept RTMP and produce HLS.publisher: an ffmpeg container that loops a sample video and pushes it to the RTMP ingest (useful for testing).viewer: a simple static nginx used to hostplayer.htmlso you can open a browser UI.
1) nginx-rtmp service
Example docker-compose service snippet:
nginx-rtmp:
build:
context: .
dockerfile: Docker/rtmp.Dockerfile
ports:
- "1935:1935" # RTMP
- "8181:80" # HLS / HTTP
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- /tmp/hls:/tmp/hls
- ./videos:/var/recordings:rw
Dockerfile (Docker/rtmp.Dockerfile):
FROM debian:bookworm-slim
RUN apt-get update && \
apt-get install -y nginx libnginx-mod-rtmp && \
apt-get clean && rm -rf /var/lib/apt/lists/*
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 1935 80
CMD ["nginx", "-g", "daemon off;"]
Notes:
- We copy
nginx.confdirectly so the RTMP module and HLS paths are configured as shown below. - Mounting
/tmp/hlsmakes HLS segments visible on the host for debugging.
2) nginx configuration
Save this as nginx.conf (the repo already contains the file). Key points:
- load the RTMP module
- set
hls onandhls_pathinside the RTMP application - expose the HLS folder via the HTTP server with correct MIME types and CORS headers
Example nginx.conf (trimmed for clarity):
worker_processes auto;
load_module modules/ngx_rtmp_module.so;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
root /var/www/html;
index index.html;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
}
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
hls on;
hls_path /tmp/hls;
hls_fragment 3s;
hls_playlist_length 60s;
# optional recording settings
record all;
record_path /var/recordings;
record_unique on;
record_suffix .flv;
}
}
}
3) publisher (test source)
This service uses the jrottenberg/ffmpeg image to loop a local video and push to the RTMP server for testing.
publisher:
image: jrottenberg/ffmpeg:4.1-alpine
command: ["-re", "-stream_loop", "-1", "-i", "/videos/input.mp4", "-c", "copy", "-f", "flv", "rtmp://nginx-rtmp:1935/live/stream-test"]
depends_on:
- nginx-rtmp
volumes:
- ./videos:/videos:ro
If you prefer to publish from your machine or OBS, use rtmp://localhost:1935/live/stream-test as the target.
4) viewer (static player)
Host player.html with a plain nginx container so you can open http://localhost:8081 in a browser.
viewer:
image: nginx:latest
ports:
- "8081:80"
volumes:
- ./player.html:/usr/share/nginx/html/index.html:ro
depends_on:
- nginx-rtmp
- publisher
Quickstart
-
Build and start the services:
docker compose up -d --build -
If you use the included
publisherservice, it will continuously push/videos/input.mp4to the RTMP server. -
Open the viewer UI and point it at the HLS playlist:
http://localhost:8081/?url=http://localhost:8181/hls/stream-test.m3u8Or open the HLS playlist directly in a player (VLC, mpv):
http://localhost:8181/hls/stream-test.m3u8
Your live streaming setup!