Owncast Self-Hosted Live Streaming Server
Owncast is an open-source self-hosted live streaming server that lets you broadcast video directly from OBS to your own server with integrated chat, without relying on Twitch, YouTube, or other platforms. With support for HLS delivery, custom branding, S3 storage for recordings, and CDN integration, Owncast gives you full control over your live streaming infrastructure.
Prerequisites
- Ubuntu 20.04+, Debian 11+, or CentOS/Rocky 8+
- Minimum 2 vCPU, 2 GB RAM (more for higher-quality streams)
- FFmpeg installed
- Root or sudo access
- A domain name for HTTPS access
- Open ports: TCP 8080 (web), TCP 1935 (RTMP ingest)
Installing Owncast
Quick install script:
# Install dependencies
sudo apt install -y ffmpeg curl
# Create Owncast directory and user
sudo useradd -r -m -d /opt/owncast -s /bin/false owncast
sudo mkdir -p /opt/owncast
cd /opt/owncast
# Download and run the installer
curl -s https://owncast.online/install.sh | bash
Manual installation:
# Download the latest release
OWNCAST_VERSION="0.1.3"
curl -LO "https://github.com/owncast/owncast/releases/download/v${OWNCAST_VERSION}/owncast-${OWNCAST_VERSION}-linux-64bit.zip"
# Extract
sudo apt install -y unzip
unzip owncast-${OWNCAST_VERSION}-linux-64bit.zip -d /opt/owncast/
# Set permissions
sudo chown -R owncast:owncast /opt/owncast/
sudo chmod +x /opt/owncast/owncast
Create a systemd service:
sudo tee /etc/systemd/system/owncast.service <<'EOF'
[Unit]
Description=Owncast Live Streaming Server
After=network.target
[Service]
User=owncast
Group=owncast
WorkingDirectory=/opt/owncast
ExecStart=/opt/owncast/owncast
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now owncast
# Check status
sudo systemctl status owncast
sudo journalctl -u owncast -f
Open required ports:
# Web interface and HLS delivery
sudo ufw allow 8080/tcp
# RTMP ingest from OBS
sudo ufw allow 1935/tcp
# CentOS/Rocky
sudo firewall-cmd --add-port=8080/tcp --add-port=1935/tcp --permanent
sudo firewall-cmd --reload
Configuring OBS Studio
- Open OBS Studio on your streaming machine
- Go to Settings > Stream
- Set Service to Custom...
- Set Server:
rtmp://your-server-ip/live - Set Stream Key: retrieve from the Owncast admin panel
- Click OK and start streaming
Get your stream key:
# Access admin panel at http://your-server:8080/admin
# Default credentials: admin / abc123
# Go to Configuration > Server Setup to find the stream key
Recommended OBS output settings for Owncast:
| Setting | Value |
|---|---|
| Encoder | x264 or NVENC H.264 |
| Rate Control | CBR |
| Bitrate | 2500-6000 kbps |
| Keyframe Interval | 2 seconds |
| Profile | high |
| Resolution | 1280x720 or 1920x1080 |
| FPS | 30 |
Admin Panel Configuration
Access the admin panel at http://your-server:8080/admin:
Change admin password immediately:
- Go to Configuration > Server Setup
- Update the admin password
- Change the stream key to something unique
Configure video quality/output variants:
# Via admin panel: Video > Video Configuration
# Add output variants for adaptive bitrate:
# High quality (for fast viewers)
Video Bitrate: 3000 kbps
Audio Bitrate: 192 kbps
Framerate: 30
Resolution: 1280x720
# Low quality (for mobile/slow connections)
Video Bitrate: 800 kbps
Audio Bitrate: 128 kbps
Framerate: 24
Resolution: 854x480
Configure stream latency:
Low Latency: 2-4 seconds (higher server load)
Normal: 8-12 seconds (default, lower load)
High Latency: 15-20 seconds (for unstable connections)
Custom Branding and Theme
# Customize via Admin > Configuration > General
# Set:
# - Server name
# - Stream description
# - Site URL
# - Logo (upload an image)
# - Tags
Custom CSS via admin panel (Appearance > Custom Styles):
/* Example: change primary color scheme */
:root {
--owncast-purple: #6441a5;
}
.online-status {
color: var(--owncast-purple);
}
/* Customize chat appearance */
.chat-message {
font-size: 14px;
}
Custom JavaScript for advanced features:
// Admin > Configuration > Advanced > Custom JavaScript
// Example: show viewer count in page title
setInterval(() => {
fetch('/api/status')
.then(r => r.json())
.then(data => {
document.title = `${data.viewerCount} viewers - MyStream`;
});
}, 10000);
S3 Storage for Recordings
Store stream recordings and segments in S3-compatible storage:
# Configure in Admin > Configuration > Storage
# Settings:
# - Enabled: true
# - Endpoint: s3.amazonaws.com (or compatible endpoint)
# - Access Key: your-access-key
# - Secret Key: your-secret-key
# - Bucket: your-bucket-name
# - Region: us-east-1
# - Path prefix: owncast/
For S3-compatible storage (Wasabi, Backblaze, MinIO):
# Example with MinIO self-hosted
# Endpoint: http://your-minio-server:9000
# Force path style: true (required for MinIO)
Automated recording to local disk:
# Configure recording in Admin > Configuration > Video
# Owncast will save segments to /opt/owncast/data/hls/ during streams
# Archive them after the stream:
sudo tee /opt/owncast/archive-stream.sh <<'EOF'
#!/bin/bash
ARCHIVE_DIR="/recordings/$(date +%Y-%m-%d_%H-%M-%S)"
mkdir -p "$ARCHIVE_DIR"
ffmpeg -i /opt/owncast/data/hls/stream.m3u8 \
-c copy "$ARCHIVE_DIR/stream.mp4"
EOF
chmod +x /opt/owncast/archive-stream.sh
Reverse Proxy with Nginx
# /etc/nginx/sites-available/owncast
server {
listen 80;
server_name stream.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name stream.example.com;
ssl_certificate /etc/letsencrypt/live/stream.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/stream.example.com/privkey.pem;
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";
}
}
sudo ln -s /etc/nginx/sites-available/owncast /etc/nginx/sites-enabled/
sudo certbot --nginx -d stream.example.com
# Update Owncast site URL in admin after enabling HTTPS
# Admin > Configuration > General > Server URL: https://stream.example.com
Chat Moderation
Chat moderation via the admin panel:
- Go to Chat > Messages to see live chat
- Click on any message to ban/suspend users
- Set Admin > Chat > Messages > Require account to reduce spam
Configure external authentication for chat:
# Admin > Configuration > Access Control
# Enable "Users must be authenticated to chat"
# Set authentication type: IndieAuth or Username/Password
Automated moderation rules:
# Set prohibited words in Admin > Chat > Moderation
# Words are matched case-insensitively
# Users who post prohibited words are auto-banned
Troubleshooting
OBS cannot connect (RTMP connection refused):
# Verify Owncast is listening on RTMP port
sudo ss -tlnp | grep 1935
# Check Owncast logs
sudo journalctl -u owncast -n 50
# Verify firewall
sudo ufw status | grep 1935
Stream starts but viewers see buffering:
# Check server CPU during streaming
top -d 1
# Reduce video quality settings
# Admin > Video > Lower bitrate or disable high-quality variants
# Check Owncast uses enough CPU for transcoding
# FFmpeg transcoding is CPU-intensive — consider hardware acceleration
No video in browser (blank player):
# Check HLS segments are being generated
ls /opt/owncast/data/hls/
# Verify FFmpeg is working
ffmpeg -version
# Check for FFmpeg errors in logs
sudo journalctl -u owncast | grep -i "ffmpeg\|error"
Conclusion
Owncast provides a complete self-hosted live streaming infrastructure with chat, adaptive bitrate delivery, and S3 recording capabilities, giving you an independent broadcasting platform that isn't subject to takedowns, algorithm changes, or platform policies. By pairing Owncast with Nginx TLS termination and configuring multiple quality variants, you can deliver a professional streaming experience to viewers on any connection speed without the bandwidth costs of routing everything through a CDN.


