Twitch and YouTube Live work fine until you want to: charge for access, ban specific countries, embed on your own site without a watermark, run a 24/7 radio station, or just not have your content live on a platform that could deprecate, demonetize, or delete you. Owncast and AzuraCast are the open-source answers — Owncast for live video (Twitch alternative), AzuraCast for internet radio with a full DJ panel.
This guide installs both on a single VPS via Docker, configures HTTPS for both, sets up RTMP ingest for video streams, and gets a radio station broadcasting. The most important part — bandwidth math — gets its own section because streaming is the one workload where bandwidth genuinely matters more than CPU.
- A Linux VPS — Ubuntu 22.04 or Debian 12, 4 GB RAM minimum, high-bandwidth plan
- A domain (or two subdomains — one for video, one for radio)
- OBS Studio or similar (for video streaming) / a music library (for radio)
- Roughly 40 minutes
Our Streaming VPS plans ship with both Owncast + AzuraCast pre-installed and bandwidth tiers sized for streaming (5 TB to 30 TB/month).
1. Bandwidth math — read this first
Streaming is the one self-hosted workload where bandwidth dominates the cost equation. A 1080p video stream at 5 Mbps × 50 concurrent viewers × 1 hour = 112 GB of egress. Per hour.
Quick reference:
| Stream type | Bitrate | Per listener/viewer/hour | 100 concurrent for 1 hour = |
|---|---|---|---|
| Internet radio (low quality) | 96 kbps | ~43 MB | 4.3 GB |
| Internet radio (high quality) | 192 kbps | ~86 MB | 8.6 GB |
| 720p video | 2.5 Mbps | ~1.1 GB | 110 GB |
| 1080p video | 5 Mbps | ~2.25 GB | 225 GB |
| 4K video | 15 Mbps | ~6.75 GB | 675 GB |
Pick your plan based on expected concurrent viewers × hours per month, not RAM or CPU. A radio station with 50 concurrent listeners 24/7 needs ~150 GB egress per day = ~4.5 TB/month. See our bandwidth explainer for more.
2. Prepare the VPS
apt update && apt upgrade -y
apt install -y curl ca-certificates gnupg ufw
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 1935/tcp # RTMP ingest (Owncast)
ufw --force enable
adduser stream
usermod -aG sudo stream
rsync --archive --chown=stream:stream ~/.ssh /home/stream
3. Install Docker
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
usermod -aG docker stream
4. Deploy Owncast (live video)
Owncast is a single-binary Go application — light footprint, simple operation. Deploy via Docker:
su - stream
mkdir -p ~/owncast/data
cd ~/owncast
cat > compose.yaml <<'EOF'
services:
owncast:
image: owncast/owncast:latest
container_name: owncast
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080" # web (behind Nginx)
- "1935:1935" # RTMP ingest (public)
volumes:
- ./data:/app/data
EOF
docker compose up -d
docker compose logs --tail 20
Owncast is now running on localhost port 8080. Default admin credentials: admin / abc123 — change immediately at http://localhost:8080/admin (SSH-tunnel if you're remote, or wait until step 7 when Nginx is up).
5. Configure OBS for RTMP streaming
In Owncast admin: Configuration → Stream Keys. Note the default stream key (you can regenerate).
In OBS Studio: Settings → Stream:
- Service: Custom...
- Server:
rtmp://your-vps-ip:1935/live - Stream Key: (the key from Owncast admin)
Output settings: 2500 kbps for 720p, 5000 kbps for 1080p, x264 encoder, 30 fps. Click Start Streaming in OBS — within 5 seconds Owncast's web player shows your live feed.
Viewers go to https://video.example.com/ (the public URL after we set up Nginx in step 7). They see chat, viewer count, and your stream.
6. Deploy AzuraCast (internet radio)
AzuraCast is more substantial — includes a DJ scheduler, listener stats, library manager, and supports multiple stations on one server. Use their official installer:
su - stream
mkdir -p ~/azuracast
cd ~/azuracast
curl -L https://raw.githubusercontent.com/AzuraCast/AzuraCast/main/docker.sh > docker.sh
chmod a+x docker.sh
./docker.sh install
The installer asks for a base URL (use radio.example.com), generates a docker-compose stack, and starts everything. Takes 4–6 minutes.
Visit http://your-vps-ip to complete the web setup. Create the first super-admin account, then create your first station. Upload music via the web file manager or SFTP into /var/azuracast/stations/<station-name>/media/.
Set up the AutoDJ playlist, schedule it 24/7, click Start Station. Listeners get a public URL like https://radio.example.com/listen/your-station/radio.mp3 they can play in any audio player, in Winamp, on their Sonos, in the browser.
🐾 Pre-tuned for streaming bandwidth
Our Streaming VPS plans ship with Owncast + AzuraCast pre-installed and bandwidth tiers sized for streaming workloads — 5 TB on Starter, 30 TB on Premium. No surprise overage bills.
See Streaming VPS Plans →7. Nginx reverse proxy + HTTPS
Both services need HTTPS for modern browsers to play smoothly.
sudo apt install -y nginx certbot python3-certbot-nginx
# Owncast vhost
sudo tee /etc/nginx/sites-available/owncast <<'EOF'
server {
listen 80;
server_name video.example.com;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/owncast /etc/nginx/sites-enabled/
# AzuraCast — installer already wrote a config; just renew certs through certbot
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d video.example.com -d radio.example.com
8. DMCA, copyright, and region-aware hosting
This matters more than it should. Streaming licensed content (Hollywood movies, sports broadcasts, pop music without ASCAP/BMI licenses) gets you DMCA takedown notices. Three notices typically = account terminated by your VPS host.
Pick your region intentionally. US, UK, France, Germany — strict DMCA / GEMA enforcement. Frankfurt, Helsinki, Singapore — generally more permissive but still respect copyright laws. None of this is legal advice; consult a lawyer if you're operating commercially.
Original or licensed content only. The legitimate use cases:
- Original podcast / music you wrote and own the rights to
- Licensed background music (Royalty-Free Music libraries, Creative Commons)
- Public domain works
- Properly-licensed broadcast via SoundExchange / ASCAP / BMI
AzuraCast has built-in support for required broadcast logging (track titles, durations, listener counts) that licensing agencies request.
9. Reference: codecs, bitrates, scaling
Video codec choice (Owncast)
| Codec | Compatibility | CPU cost | File size |
|---|---|---|---|
| H.264 / AVC | Universal — every browser, smart TV, mobile | Low | Standard |
| H.265 / HEVC | iOS 11+, Safari, modern Android | High | ~50% smaller |
| AV1 | Chrome / Firefox / Edge — no Safari, no iOS | Very high | ~30% smaller than HEVC |
For live streaming, H.264 is the right answer. HEVC is tempting but Safari/iOS are picky about it in HLS streams, and the CPU cost of encoding in real time outweighs the bandwidth saving on a VPS.
Audio codec choice (AzuraCast)
- MP3 (192 kbps) — universal compatibility, decent quality
- AAC (128 kbps) — better quality at lower bitrate, slightly less universal
- Opus (96 kbps) — best quality per bit, but not all clients support it
Per-plan capacity
| Plan | 1080p video viewers | 192kbps radio listeners |
|---|---|---|
| Starter ($7.99, 5 TB) | ~30 concurrent (8 hrs/day) | ~800 concurrent (24/7) |
| Pro ($15.99, 15 TB) | ~100 concurrent (8 hrs/day) | ~2400 concurrent (24/7) |
| Premium ($35.99, 30 TB) | ~250 concurrent (8 hrs/day) | ~5000 concurrent (24/7) |
Scaling beyond one VPS
For larger audiences (1000+ concurrent video viewers), use a CDN in front of Owncast — Bunny CDN ($0.005/GB), Cloudflare Stream, or self-hosted with Nginx + cache nodes. Both Owncast and AzuraCast support CDN integration via custom edge URLs.
FAQ
Owncast vs Twitch?
Owncast wins on: control (no platform policies, no demonetization, no surprise bans), embedding (clean iframe, no overlay ads), and economics (no platform cut, you own the audience data). Twitch wins on: discovery (millions of viewers browse there daily), social features (clips, raids, follower mechanics), and zero infrastructure cost. Use Owncast for content you already have an audience for. Use Twitch when you're trying to grow an audience from zero.
Can I run Owncast and AzuraCast on the same VPS?
Yes — that's what this guide does. Both run in separate Docker containers, each gets its own subdomain. The Pro plan ($15.99, 8 GB RAM) handles both comfortably; AzuraCast wants ~2 GB RAM idle, Owncast wants ~500 MB.
What about a Plex-like 'watch later' on Owncast?
Not natively — Owncast is live-only by design. For VOD (video on demand), use Jellyfin (tutorial) on the same VPS. Owncast can record streams to disk; you then move recordings to Jellyfin for replay.
Do I need a CDN?
For under ~100 concurrent viewers, no — the VPS handles it directly. For larger audiences, a CDN amortizes bandwidth across edge servers and reduces single-server load. Bunny CDN at $0.005/GB is cheaper than most VPS bandwidth at scale.
Can listeners pay for access?
Owncast has 'token' support — generate stream keys per user, gate the stream behind login. AzuraCast supports listener authentication via streaming URL tokens. Pair either with Stripe or a membership platform for actual payment processing.
Why no IPTV-restream guide?
Because 99% of IPTV restream use cases involve licensed content (Hollywood, sports, broadcast TV) where redistribution is illegal in most countries. Original content, public domain, and properly-licensed restreaming are fine — and use the same Owncast / Nginx-RTMP stack we cover here.