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:
- Self-hosted with NGINX-RTMP: Free, full control, requires Linux skills and ongoing maintenance
- Self-hosted with Flussonic or Wowza: Commercial software with better features but $300–2000/mo licensing
- 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
- Provision a properly-sized server
- Install NGINX with RTMP module
- Use FFmpeg to pull source streams in
- Configure NGINX to output HLS
- Test with VLC
- Wire output into your panel
- Scale carefully (don't try 5,000 channels day one)
- Monitor and harden
Or skip steps 1–8 and order a managed restream — your call.