You've decided you need to restream. Now what? This guide walks through the practical steps to actually set up a working restream — from picking your approach to getting your first stream live for customers.

Step 0: Pick your path

Before you write a single line of config, decide your approach:

  1. Self-hosted with NGINX-RTMP: Free, full control, requires Linux skills and ongoing maintenance
  2. Self-hosted with Flussonic or Wowza: Commercial software with better features but $300–2000/mo licensing
  3. Managed restream service: Pay someone else to handle infrastructure; you focus on customers

This guide covers the self-hosted NGINX-RTMP path because it's the most common DIY route. If you want managed, that's a different process — you basically send us your source URL and we handle everything.

Step 1: Provision your server

Minimum specs for a starter restream server (50 concurrent viewers):

  • 4 vCPU dedicated cores
  • 8 GB RAM
  • 100 GB SSD
  • 1 Gbps unmetered bandwidth
  • Ubuntu 22.04 LTS

For 250+ viewers, double everything. Use our bandwidth calculator to size correctly — under-provisioning is the #1 reason restream setups fail in their first week.

Provider tips: Avoid the cheapest VPS providers ($5/mo deals); they oversell bandwidth and your stream will choke during peak. OVH, Hetzner, Vultr, and DigitalOcean are reliable starting points.

Step 2: Install NGINX with RTMP module

Stock NGINX doesn't include RTMP — you have to compile from source. Full instructions are in our NGINX-RTMP setup guide. The short version:

cd /usr/src
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzf nginx-1.24.0.tar.gz
git clone https://github.com/arut/nginx-rtmp-module.git
cd nginx-1.24.0
./configure --add-module=/usr/src/nginx-rtmp-module \
  --with-http_ssl_module --with-http_v2_module
make && make install

Step 3: Configure ingest from your source

The trickiest part. Your source can be in many formats — here's how to ingest each:

Source: M3U playlist URL

Use FFmpeg to pull the playlist and forward each channel into NGINX as RTMP:

#!/bin/bash
# /usr/local/bin/restream-channel1.sh
ffmpeg -re -i "http://supplier.example.com/live/user/pass/123.m3u8" \
  -c copy -f flv rtmp://127.0.0.1/live/channel1

Run as a systemd service so it auto-restarts on failure:

# /etc/systemd/system/restream-channel1.service
[Unit]
Description=Restream Channel 1
After=network.target

[Service]
ExecStart=/usr/local/bin/restream-channel1.sh
Restart=always
RestartSec=5
User=nobody

[Install]
WantedBy=multi-user.target
systemctl enable restream-channel1
systemctl start restream-channel1

Source: Xtream Codes credentials

Same idea, but the URL format is:

http://server:port/live/USERNAME/PASSWORD/CHANNEL_ID.ts

Source: RTMP feed

If your supplier provides RTMP, you can chain RTMP-to-RTMP without re-encoding:

ffmpeg -i rtmp://supplier.example.com/live/streamkey \
  -c copy -f flv rtmp://127.0.0.1/live/channel1

Step 4: Configure NGINX HLS output

In /etc/nginx/nginx.conf:

rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        application live {
            live on;
            record off;
            hls on;
            hls_path /var/www/hls;
            hls_fragment 4s;
            hls_playlist_length 60s;

            allow publish 127.0.0.1;
            deny publish all;
            allow play all;
        }
    }
}

http {
    server {
        listen 80;
        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /var/www;
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }
    }
}

Step 5: Test the output

Once your FFmpeg pull is running and NGINX is configured, your restream output URL is:

http://your-server-ip/hls/channel1.m3u8

Test in VLC: Media → Open Network Stream → paste URL. You should see the channel play within 5–10 seconds. If it doesn't:

  • Check FFmpeg logs: journalctl -u restream-channel1 -f
  • Check NGINX RTMP stats: http://your-server-ip/stat
  • Verify HLS files are being written: ls /var/www/hls/

Step 6: Wire output into your panel

Your IPTV panel (Xtream Codes, XUI.ONE, Ministra) needs to know about the restream output. In your panel's stream manager, add a new stream with:

  • Source URL: http://localhost/hls/channel1.m3u8 (or full URL if panel is on a different server)
  • Stream type: HLS
  • Channel name, logo, EPG ID: Whatever you want customers to see

Save and test from a customer-facing IPTV app (IPTV Smarters, TiviMate). The channel should now play through your restream.

Step 7: Scale to many channels

Doing the above for one channel is easy. Doing it for 5,000 channels is a project. Tips:

  • Don't run 5,000 FFmpeg processes — each consumes RAM. Use a smarter approach like Flussonic's auto-pull or a custom orchestrator that only pulls active channels (channels with live viewers).
  • Use connection-on-demand: Many panels support pulling streams only when a viewer requests them, then dropping the pull when no viewers remain. This dramatically reduces idle bandwidth.
  • Multiple workers: Once you exceed 200 active channels, split across multiple NGINX worker servers behind a load balancer.

Step 8: Monitor and harden

Get monitoring in place before you onboard customers:

  • Uptime monitoring on your panel and stream URLs
  • Bandwidth alerts (catches DDoS attacks early)
  • Disk space alerts (HLS chunks fill disk fast if cleanup fails)
  • FFmpeg process health checks

And harden the server: see our IPTV server hardening guide for the full checklist (SSH lockdown, fail2ban, firewall, kernel tuning).

Honest reality check

The above is the happy path. Real restream operations deal with:

  • Source suppliers swapping URLs without warning
  • DDoS attacks (peer competitors hire $20 booter services to take you down)
  • Codec mismatches that work in VLC but not in customer IPTV apps
  • EPG mapping nightmares
  • Customer support tickets at 2 AM

This is why most resellers eventually move to a managed restream service. You spend $149/mo instead of $80/mo on infrastructure, but you get to sleep at night.

Quick recap

  1. Provision a properly-sized server
  2. Install NGINX with RTMP module
  3. Use FFmpeg to pull source streams in
  4. Configure NGINX to output HLS
  5. Test with VLC
  6. Wire output into your panel
  7. Scale carefully (don't try 5,000 channels day one)
  8. Monitor and harden

Or skip steps 1–8 and order a managed restream — your call.