Setting Up Live Streaming Infrastructure on Dedicated Servers
Building a Live Streaming Dedicated Server Setup gives you full control, performance, and reliability for professional-grade streaming. This guide will show you how to create a complete pipeline using open-source tools and best practices.
You will learn how to handle RTMP and SRT ingest, perform CPU and GPU-accelerated transcoding with FFmpeg, and generate HLS and CMAF streams ready for web and mobile delivery. Also, to ensure the live streaming platform is secure, we will cover TLS encryption, token-based security, and monitoring.
This setup guide will help you deploy a powerful and flexible live streaming infrastructure on PerLod’s dedicated Linux servers.
Table of Contents
Prerequisites for Live Streaming Dedicated Server Setup
Before you start setting up your dedicated server for live streaming, you need to prepare your server.
The recommended hardware specifications:
- CPU Only: You need about 6–10 vCPUs to handle one full HD(1080p) stream that’s transcoded into three quality levels, including 1080p, 720p, and 480p.
- NVIDIA GPU (NVENC): A mid-range NVIDIA GPU can handle many streams efficiently using hardware encoding.
- RAM: Around 8–16 GB of memory is enough for a few simultaneous transcoding ladders.
- Disk: Use a fast NVMe SSD. Keep a separate fast drive or partition for storing HLS segment files. For example, /var/www/hls.
- Network: Choose a 1–10 Gbps network card, depending on how many viewers or streams you plan to support.
Note: If you’re using a GPU dedicated server, ensure your hosting provider supports NVIDIA NVENC or AMD AMF acceleration for FFmpeg.
Then, you must prepare your OS. Here, our OS is Ubuntu 24.04. Run the system update, set the correct timezone, and install the required packages with the command below:
sudo apt update && sudo apt upgrade -y
sudo timedatectl set-timezone Asia/Dubai
sudo apt install build-essential git curl unzip htop iotop iftop net-tools jq -y
You can also create an app user for your streaming with the commands below:
sudo adduser stream --disabled-password --gecos ""
sudo usermod -aG sudo stream
Next, install the UFW firewall on your Ubuntu server:
sudo apt install ufw -y
Allow the required ports, including 80, 443, 1935 for RTMP, and 9000 for SRT:
sudo ufw allow 22/tcp
sudo ufw allow 80,443/tcp
sudo ufw allow 1935/tcp
sudo ufw allow 9000/udp
Then, enable your UFW firewall with:
sudo ufw enable
At this point, you need to tune a few Linux kernel parameters to handle many connections and reduce latency. You can use the commands below to apply optimized network and system settings:
sudo tee /etc/sysctl.d/99-streaming.conf >/dev/null <<'EOF'
net.core.somaxconn = 4096
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_congestion_control = bbr
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 1024
EOF
To apply the changes, run the command below:
sudo sysctl --system
Also, you need a domain name that is pointed to your server’s IP address.
Once you are done with these requirements, proceed to the next steps to complete Live Streaming Dedicated Server Setup.
Install Nginx with RTMP Module and TLS
By default, Ubuntu 24.04 ships with the Nginx RTMP module. To install it, you can easily use the command below:
sudo apt install nginx libnginx-mod-rtmp -y
You can verify your installation with the command below:
nginx -V 2>&1 | grep -q rtmp && echo "RTMP module available"
Then, you must create a directory for your HLS output and set the correct permissions. To do this, run the commands below:
sudo mkdir -p /var/www/hls/live
sudo chown -R www-data:www-data /var/www/hls
Configure Nginx for RTMP and HLS
At this point, you need to set up Nginx to accept RTMP streams and automatically generate HLS (CMAF/fMP4) segments.
You can create or update your Nginx configuration file with the following minimal config:
sudo tee /etc/nginx/nginx.conf >/dev/null <<'EOF'
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 4096;
multi_accept on;
}
rtmp {
server {
listen 1935; # RTMP ingest
chunk_size 4096;
application live {
live on;
# Simple stream key auth via "play/publish" keys (basic)
# Push to this like: rtmp://HOST/live/STREAM_KEY
allow publish all;
allow play all;
# HLS directly from RTMP module (fMP4/CMAF style)
hls on;
hls_path /var/www/hls/live;
hls_fragment 2s;
hls_playlist_length 6s;
# CMAF/fMP4 segments (better for modern players)
hls_variant _cmaf;
hls_fragment_naming system;
hls_segments 10;
hls_cleanup on;
hls_nested on;
hls_fragment_type fmp4; # CMAF
}
}
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Basic static origin
server {
listen 80;
server_name _;
root /var/www;
location /hls/ {
add_header Cache-Control "no-cache";
add_header Access-Control-Allow-Origin "*";
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
video/iso.segment m4s;
application/octet-stream m4s;
}
autoindex off;
}
# Simple health
location /healthz { return 200 "ok\n"; }
}
}
EOF
Once you are done, test your configuration that is set correctly:
sudo nginx -t
And reload Nginx to apply the changes:
sudo systemctl restart nginx
Enable TLS with Let’s Encrypt
To secure your setup, you can install Certbot and enable HTTPS for your domain. To do this, you can use the following commands:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d stream.example.com --redirect --agree-tos -m [email protected] --no-eff-email
This creates an HTTPS server block and ensures your HLS paths are served under:
https://stream.example.com/hls/...
Install FFmpeg CPU and Optional NVIDIA NVENC
FFmpeg handles transcoding, bitrate ladder generation, and format conversion. A CPU-only setup is perfectly fine for a few 1080p streams.
For a CPU-only installation, you can install FFmpeg using the command below:
sudo apt install ffmpeg -y
Verify the installation with:
ffmpeg -version | head -n1
For optional GPU-accelerated (NVENC) encoding, you must install drivers with NVENC-capable FFmpeg. Install the drivers and reboot the system with the commands below:
sudo ubuntu-drivers autoinstall
sudo reboot
After reboot, verify the GPU with the command below:
nvidia-smi
Also, you can check that FFmpeg recognizes NVENC. To do this, run:
ffmpeg -hwaccels | grep cuda || true
ffmpeg -encoders | grep nvenc || true
If you see h264_nvenc or hevc_nvenc means hardware encoding is ready to use.
SRT Ingest to Internal RTMP Bridge
Modern live streaming dedicated server setup often use SRT (Secure Reliable Transport) for contribution, especially when broadcasting over the public internet. It provides better error recovery and lower latency than RTMP in unstable network conditions.
As you may know, Nginx with the RTMP module cannot accept SRT natively. To integrate SRT streams into the pipeline, we can use FFmpeg as a bridge. It receives the SRT input and forwards it internally to Nginx as RTMP.
You can run a bridge service via systemd. To do this, run the command below:
sudo tee /etc/systemd/system/[email protected] >/dev/null <<'EOF'
[Unit]
Description=SRT listener on port %i -> RTMP normalize
After=network.target nginx.service
[Service]
Type=simple
ExecStart=/usr/bin/ffmpeg -loglevel warning \
-re -i "srt://0.0.0.0:%i?mode=listener&latency=80&linger=1" \
-c copy -f flv "rtmp://127.0.0.1/live/%i"
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
EOF
Enable the service and check for the status with:
sudo systemctl daemon-reload
sudo systemctl enable --now [email protected]
sudo systemctl status [email protected] --no-pager
This bridge allows your server to accept SRT ingest while keeping the rest of your RTMP-based workflow safe and healthy.
Automatic Transcoding to an ABR Ladder
To deliver smooth playback across different devices and network conditions, each live stream should be transcoded into multiple quality levels, which is known as an Adaptive Bitrate (ABR) ladder.
In this step, we want to create a fully automated process that converts one incoming stream into three H.264 CMAF/HLS renditions, including 1080p, 720p, and 480p.
While Nginx-RTMP can trigger transcoding automatically using the exec directive, managing these jobs through systemd is more reliable and easier to monitor. Each live stream or stream key runs its own supervised FFmpeg process, ensuring stability and automatic restarts if a transcode stops.
Now create a script at /usr/local/bin/transcode-cmaf.sh that converts an RTMP live stream into multiple HLS video qualities:
sudo tee /usr/local/bin/transcode-cmaf.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
KEY="${1:?stream key required}"
INPUT="rtmp://127.0.0.1/live/${KEY}"
OUTDIR="/var/www/hls/live/${KEY}"
PLAYLIST="${OUTDIR}/index.m3u8"
mkdir -p "$OUTDIR"
ffmpeg -hide_banner -loglevel warning -threads 2 \
-i "$INPUT" \
-filter_complex "[0:v]split=3[v1080][v720][v480]; \
[v1080]scale=w=1920:h=1080:flags=bicubic[v1080o]; \
[v720] scale=w=1280:h=720:flags=bicubic[v720o]; \
[v480] scale=w=854:h=480:flags=bicubic[v480o]" \
-map "[v1080o]" -map a? -c:v libx264 -preset veryfast -tune zerolatency -profile:v high -level:v 4.1 -b:v 5500k -maxrate 6000k -bufsize 8000k -g 48 -keyint_min 48 -sc_threshold 0 -c:a aac -b:a 160k \
-map "[v720o]" -map a? -c:v libx264 -preset veryfast -tune zerolatency -profile:v high -level:v 4.0 -b:v 3000k -maxrate 3300k -bufsize 4800k -g 48 -keyint_min 48 -sc_threshold 0 -c:a aac -b:a 128k \
-map "[v480o]" -map a? -c:v libx264 -preset veryfast -tune zerolatency -profile:v main -level:v 3.1 -b:v 1300k -maxrate 1500k -bufsize 2200k -g 48 -keyint_min 48 -sc_threshold 0 -c:a aac -b:a 96k \
-f hls \
-hls_time 2 -hls_list_size 6 -hls_flags independent_segments+delete_segments+append_list \
-hls_segment_type fmp4 -hls_playlist_type event \
-master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0,name:1080 v:1,a:1,name:720 v:2,a:2,name:480" \
-hls_segment_filename "${OUTDIR}/%v/seg_%06d.m4s" \
"${OUTDIR}/%v/index.m3u8"
EOF
Make it executable with:
sudo chmod +x /usr/local/bin/transcode-cmaf.sh
Then, create a systemd service that automatically runs the transcode script for any stream key:
sudo tee /etc/systemd/system/[email protected] >/dev/null <<'EOF'
[Unit]
Description=Transcode RTMP stream %i to CMAF HLS ABR
After=network.target nginx.service
[Service]
Type=simple
ExecStart=/usr/local/bin/transcode-cmaf.sh %i
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
EOF
To apply the changes, run the command below:
sudo systemctl daemon-reload
Next, you can start the transcode service immediately for a stream key. For example, for myevent stream key:
sudo systemctl enable --now [email protected]
Also, you can check live logs from the transcoding process with:
journalctl -u [email protected] -f
To set up the streaming workflow, follow these steps:
Push from OBS for RTMP with the myevent stream key:
rtmp://stream.example.com/live
Then run:
sudo systemctl enable --now [email protected]
For SRT push from OBS on port 9000. Then run:
sudo systemctl enable --now [email protected]
The transcoder will automatically convert your stream into multiple HLS qualities for playback.
For GPU-accelerated NVIDIA NVENC, you need to replace the CPU encoding with:
-c:v h264_nvenc -preset p4 -tune ll -rc vbr -cq 23
Or you can target -b:v/-maxrate similarly. For example, for 1080p:
-c:v h264_nvenc -preset p4 -tune ll -rc vbr -b:v 5500k -maxrate 6000k -bufsize 8000k -g 48 -bf 2 -temporal-aq 1 -spatial-aq 1
Apply these settings for 720p and 480p.
Create Live Stream Player Page
At this point, you can create a player page that automatically loads and plays the current broadcast.
To create the player HTML file, run the command below:
sudo tee /var/www/html/player.html >/dev/null <<'EOF'
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Live Player</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>body{margin:0;background:#111;color:#eee;font-family:sans-serif} .wrap{max-width:900px;margin:40px auto;padding:20px} video{width:100%;max-height:70vh;background:#000}</style>
</head>
<body>
<div class="wrap">
<h1>Live Player</h1>
<video id="video" controls playsinline></video>
<p id="status"></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
const master = location.origin + "/hls/live/myevent/master.m3u8";
const video = document.getElementById('video');
if (Hls.isSupported()) {
const hls = new Hls({ lowLatencyMode: true, backBufferLength: 30 });
hls.loadSource(master);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, () => video.play());
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = master; video.addEventListener('loadedmetadata', () => video.play());
} else {
document.getElementById('status').textContent = "HLS not supported in this browser.";
}
</script>
</body>
</html>
EOF
Then you can access it at:
https://stream.example.com/player.html
Secure Your Live Stream: Publish and Playback Protection
At this point, you can secure both RTMP publishing with private stream keys and HLS playback with signed URLs using Nginx’s secure_link module.
For stream keys RTMP, OBS uses rtmp://HOST/live/STREAM_KEY. Keep these keys private and rotate them per event.
You can also add a secret and URL pattern in your Nginx server block with:
location /hls/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri SECRETSTRING";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
add_header Cache-Control "no-cache";
add_header Access-Control-Allow-Origin "*";
# ...types...
}
Then, generate signed URLs in your app:
expires = UNIX_TIMESTAMP_IN_FUTURE
token = base64url(md5(expires + path + SECRETSTRING))
GET /hls/live/myevent/master.m3u8?md5=token&expires=expires
The player would request signed URLs from your backend instead of accessing HLS files directly.
Monitor Live Stream Performance
It is recommended to keep your live stream running smoothly with comprehensive monitoring. You must track viewer counts, stream health, and system resources to quickly identify and resolve issues before they impact your audience.
You can monitor active streams, viewers, and bandwidth usage with Nginx’s built-in RTMP statistics page. Add the Nginx RTMP stats to your config file in http{}:
server {
listen 8080;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/share/doc/libnginx-mod-rtmp/examples/;
}
}
Check for syntax errors and reload Nginx to apply the changes:
sudo nginx -t && sudo systemctl reload nginx
Now start monitoring stats with the following curl command:
curl http://127.0.0.1:8080/stat
You can also check for system health and process monitoring. You can track transcoder performance, resource usage, and service logs with the commands below:
sudo journalctl -u srt-to-rtmp@9000 -f
sudo journalctl -u transcode@myevent -f
htop
iotop -oPa
sudo nginx -T | less
Archive Live Streams: Recording and Video-on-Demand
You can also automatically record your live streams while they’re broadcasting to create instant video-on-demand assets for later viewing and distribution. To do this, you can append this to your FFmpeg command:
-map 0:v -map a? -c copy -f mp4 -movflags +frag_keyframe+empty_moov "/var/www/hls/live/${KEY}/archive-$(date +%Y%m%dT%H%M%S).mp4"
This creates files like archive. mp4 for later viewing or editing.
That’s it, you are done with Live Streaming Dedicated Server Setup.
FAQs
What operating system is best for a live streaming server?
Ubuntu Linux is the most stable and widely supported choice for streaming infrastructure. It offers excellent performance, driver support, and package availability for tools like Nginx, FFmpeg, and Certbot.
Which protocol should I use for ingest, RTMP or SRT?
Use SRT for professional contributions and use RTMP for compatibility with tools like OBS. You can bridge between them with FFmpeg.
Can I use GPU acceleration to reduce CPU load?
Yes. NVIDIA GPUs with NVENC significantly reduce CPU usage and can handle multiple simultaneous transcodes.
Conclusion
Live Streaming Dedicated Server Setup gives you complete control over quality, scalability, and cost. By using open-source tools like Nginx-RTMP, FFmpeg, and Certbot, you can create a professional-grade streaming workflow. We hope you enjoy this guide.
Subscribe to our X and Facebook channels to get the latest articles for Live streaming servers.
For further reading:
Low Latency Game Servers for Faster Performance