Setting Up Live Streaming Infrastructure on Dedicated Servers

Updated on Apr 16, 2026
Kimberly N
11 MINS READ
Table of Contents
Live Streaming Dedicated Server Setup

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.

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:

Bash
sudo apt update && sudo apt upgrade -ysudo timedatectl set-timezone Asia/Dubaisudo 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:

Bash
sudo adduser stream --disabled-password --gecos ""sudo usermod -aG sudo stream

Next, install the UFW firewall on your Ubuntu server:

Bash
sudo apt install ufw -y

Allow the required ports, including 80, 443, 1935 for RTMP, and 9000 for SRT:

Bash
sudo ufw allow 22/tcpsudo ufw allow 80,443/tcpsudo ufw allow 1935/tcpsudo ufw allow 9000/udp

Then, enable your UFW firewall with:

Bash
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:

Bash
sudo tee /etc/sysctl.d/99-streaming.conf >/dev/null <<'EOF'net.core.somaxconn = 4096net.core.rmem_max = 268435456net.core.wmem_max = 268435456net.ipv4.tcp_fastopen = 3net.ipv4.tcp_congestion_control = bbrfs.inotify.max_user_watches = 524288fs.inotify.max_user_instances = 1024EOF

To apply the changes, run the command below:

Bash
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 the 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:

Bash
sudo apt install nginx libnginx-mod-rtmp -y

You can verify your installation with the command below:

Bash
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:

Bash
sudo mkdir -p /var/www/hls/livesudo 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:

NGINX
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;        chunk_size 4096;         application live {            live on;             allow publish all;            allow play all;             hls on;            hls_path /var/www/hls/live;            hls_fragment 2s;            hls_playlist_length 6s;             hls_variant _cmaf;            hls_fragment_naming system;            hls_segments 10;            hls_cleanup on;            hls_nested on;            hls_fragment_type fmp4;        }    }} 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;     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;        }         location /healthz { return 200 "ok\n"; }    }}EOF

Once you are done, test your configuration to make sure it is set correctly:

Bash
sudo nginx -t

And reload Nginx to apply the changes:

Bash
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:

Bash
sudo apt install certbot python3-certbot-nginx -ysudo certbot --nginx -d stream.example.com --redirect --agree-tos -m you@example.com --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:

Bash
sudo apt install ffmpeg -y

Verify the installation with:

Bash
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:

Bash
sudo ubuntu-drivers autoinstallsudo reboot

After reboot, verify the GPU with the command below:

Bash
nvidia-smi

Also, you can check that FFmpeg recognizes NVENC. To do this, run:

Bash
ffmpeg -hwaccels | grep cuda || trueffmpeg -encoders | grep nvenc || true

If you see h264_nvenc or hevc_nvenc, hardware encoding is ready to use.

SRT Ingest to Internal RTMP Bridge

Modern live streaming dedicated server setups 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:

INI
sudo tee /etc/systemd/system/srt-to-rtmp@.service >/dev/null <<'EOF'[Unit]Description=SRT listener on port %i -> RTMP normalizeAfter=network.target nginx.service [Service]Type=simpleExecStart=/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=alwaysRestartSec=2 [Install]WantedBy=multi-user.targetEOF

Enable the service and check the status with:

Bash
sudo systemctl daemon-reloadsudo systemctl enable --now srt-to-rtmp@9000.servicesudo systemctl status srt-to-rtmp@9000.service --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:

Bash
sudo tee /usr/local/bin/transcode-cmaf.sh >/dev/null <<'EOF'#!/usr/bin/env bashset -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:

Bash
sudo chmod +x /usr/local/bin/transcode-cmaf.sh

Then, create a systemd service that automatically runs the transcode script for any stream key:

INI
sudo tee /etc/systemd/system/transcode@.service >/dev/null <<'EOF'[Unit]Description=Transcode RTMP stream %i to CMAF HLS ABRAfter=network.target nginx.service [Service]Type=simpleExecStart=/usr/local/bin/transcode-cmaf.sh %iRestart=alwaysRestartSec=2 [Install]WantedBy=multi-user.targetEOF

To apply the changes, run the command below:

Bash
sudo systemctl daemon-reload

Next, you can start the transcode service immediately for a stream key. For example, for the myevent stream key:

Bash
sudo systemctl enable --now transcode@myevent.service

Also, you can check live logs from the transcoding process with:

Bash
journalctl -u transcode@myevent.service -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:

Bash
sudo systemctl enable --now transcode@myevent.service

For SRT push from OBS on port 9000, then run:

Bash
sudo systemctl enable --now transcode@9000.service

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:

HTML
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 in 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:

NGINX
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_FUTUREtoken = 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{}:

NGINX
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:

Bash
sudo nginx -t && sudo systemctl reload nginx

Now start monitoring stats with the following curl command:

Bash
curl http://127.0.0.1:8080/stat

You can also check system health and process monitoring. You can track transcoder performance, resource usage, and service logs with the commands below:

Bash
sudo journalctl -u srt-to-rtmp@9000 -fsudo journalctl -u transcode@myevent -fhtopiotop -oPasudo 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 the live streaming dedicated server setup.

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

Advantages of GPU-Dedicated Servers for Video Editing

Enhancing 3D Rendering on VPS

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.

Use SRT for professional contributions and use RTMP for compatibility with tools like OBS. You can bridge between them with FFmpeg.

Yes. NVIDIA GPUs with NVENC significantly reduce CPU usage and can handle multiple simultaneous transcodes.