Skip to main content

How to Self-Host Owncast: Live Streaming Server 2026

·OSSAlt Team
owncastlive-streamingself-hostingdockerfediverseobs2026

TL;DR

Owncast (MIT, ~9K GitHub stars, Go) is a self-hosted live streaming server. Stream via OBS (or any RTMP software), and viewers watch in a built-in web player with live chat — no Twitch, no YouTube, no platform rules. Owncast integrates with the Fediverse (Mastodon, etc.) so followers get notified when you go live. Twitch takes 50% of sub revenue; Owncast is free with zero platform fees.

Key Takeaways

  • Owncast: MIT, ~9K stars, Go — self-hosted live streaming
  • OBS compatible: Stream via RTMP from any streaming software
  • Built-in chat: Real-time chat with moderation tools
  • Fediverse integration: ActivityPub — followers on Mastodon get live notifications
  • S3 storage: Offload video segments to S3/B2 for scalable delivery
  • Embeddable: Embed the player on any website
  • Single binary: No dependencies — runs on any Linux server

Part 1: Docker Setup

# docker-compose.yml
services:
  owncast:
    image: owncast/owncast:latest
    container_name: owncast
    restart: unless-stopped
    ports:
      - "8080:8080"     # Web UI + player
      - "1935:1935"     # RTMP ingest
    volumes:
      - owncast_data:/app/data

volumes:
  owncast_data:
docker compose up -d
  • Web UI: http://your-server:8080
  • Admin panel: http://your-server:8080/admin (default password: abc123 — change immediately!)

Part 2: HTTPS with Caddy

live.yourdomain.com {
    reverse_proxy localhost:8080
}

Note: RTMP (port 1935) doesn't use HTTPS — it stays on port 1935. Only the web UI needs HTTPS.


Part 3: OBS Configuration

Stream from OBS

  1. Open OBS → Settings → Stream
  2. Service: Custom...
  3. Server: rtmp://live.yourdomain.com/live
  4. Stream Key: (from Owncast admin → Configuration → Server Setup → Stream Key)
  5. Apply → Start Streaming
Output → Streaming:
  Encoder: x264 (or NVENC for GPU)
  Rate Control: CBR
  Bitrate: 2500-4500 kbps (adjust for bandwidth)
  Keyframe Interval: 2 seconds

Video:
  Base Resolution: 1920x1080
  Output Resolution: 1280x720 (for lower bandwidth)
  FPS: 30

Audio:
  Sample Rate: 48 kHz
  Bitrate: 160 kbps

Other streaming software

Any RTMP-compatible software works:

  • Streamlabs: Same RTMP URL configuration
  • FFmpeg: ffmpeg -re -i input.mp4 -c copy -f flv rtmp://live.yourdomain.com/live/STREAM_KEY
  • Restream: Forward to Owncast as a custom destination

Part 4: Admin Configuration

General settings

Admin → Configuration:
  Server Name: Your Channel Name
  Server Summary: What your stream is about
  Logo: Upload your channel logo
  Tags: gaming, coding, music (for Fediverse discovery)
  
  Stream Key: (change from default!)
  Stream Title: (update per stream)
  
  NSFW: false

Video quality

Admin → Configuration → Video:
  
  # Output variants (adaptive bitrate):
  - 720p at 2500 kbps (default)
  - 480p at 1200 kbps (low bandwidth)
  - Audio only at 128 kbps (very low bandwidth)
  
  Latency level: Low (4s) / Standard (10s) / High (20s)
  # Lower latency = more CPU, more buffering risk

Custom page content

Admin → Configuration → General:
  Extra Page Content: (Markdown)
  
  ## About This Stream
  Welcome to my channel! I stream:
  - 🎮 Indie games on Tuesdays
  - 💻 Coding sessions on Thursdays
  - 🎵 Music production on weekends
  
  ## Links
  - [Website](https://yourdomain.com)
  - [Mastodon](https://mastodon.social/@you)

Part 5: Chat and Moderation

Chat features

  • Real-time messaging
  • Custom emojis (upload in admin)
  • Username and color customization
  • Chat authentication (optional)

Moderation

Admin → Chat:
  - Require authentication to chat
  - Forbidden usernames: list
  - Forbidden words: filter list
  
Admin → Chat Users:
  - Ban users
  - Moderator role: can timeout/ban others

Chat authentication options

Admin → Configuration → Chat:
  - Anonymous chat (default)
  - IndieAuth authentication
  - Fediverse authentication (login with Mastodon account)

Part 6: Fediverse Integration

Enable ActivityPub

Admin → Configuration → Federation:
  Enable Federation: Yes
  Instance URL: https://live.yourdomain.com
  
  # Your Fediverse handle becomes:
  # @admin@live.yourdomain.com

What happens

  1. People on Mastodon/Pleroma/Pixelfed can follow @admin@live.yourdomain.com
  2. When you go live, followers get a notification post
  3. When you update the stream title, it posts an update
  4. Followers can interact (boost, reply) directly from Mastodon

Follow from Mastodon

# Search for your Owncast handle:
@admin@live.yourdomain.com

# Click Follow → receive notifications when stream goes live

Part 7: S3 Storage (Scaling)

For large audiences, offload video segments to S3/B2/MinIO:

Admin → Configuration → Storage:
  Enable S3 Storage: Yes
  Endpoint: s3.amazonaws.com (or minio.yourdomain.com)
  Access Key: AKIA...
  Secret Key: your-secret
  Bucket: owncast-stream
  Region: us-east-1
  
  # Or Backblaze B2:
  Endpoint: s3.us-west-002.backblazeb2.com
  Bucket: owncast-stream

With S3 storage:

  • Video segments are uploaded to S3 in real-time
  • Viewers download from S3/CDN instead of your server
  • Your server only handles RTMP ingest and chat
  • Scales to thousands of concurrent viewers

Part 8: Embedding

Embed player on your website

<!-- Video player only: -->
<iframe
  src="https://live.yourdomain.com/embed/video"
  width="100%"
  height="450"
  referrerpolicy="origin"
  scrolling="no"
  allowfullscreen>
</iframe>

<!-- Chat only: -->
<iframe
  src="https://live.yourdomain.com/embed/chat/readwrite"
  width="100%"
  height="500">
</iframe>

<!-- Read-only chat: -->
<iframe
  src="https://live.yourdomain.com/embed/chat/readonly"
  width="100%"
  height="500">
</iframe>

REST API

BASE="https://live.yourdomain.com"

# Check if stream is live:
curl "$BASE/api/status" | jq '{online: .online, viewerCount: .viewerCount, title: .streamTitle}'

# Get chat messages:
curl "$BASE/api/chat" | jq '.[].body'

# Send a system message (admin):
curl -X POST "$BASE/api/integrations/chat/system" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
  -d '{"body": "Stream starting in 5 minutes!"}'

Maintenance

# Update:
docker compose pull
docker compose up -d

# Backup:
tar -czf owncast-backup-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect owncast_owncast_data --format '{{.Mountpoint}}')

# Check stream health:
curl -s https://live.yourdomain.com/api/status | jq .

# Logs:
docker compose logs -f owncast

See all open source media tools at OSSAlt.com/categories/media.

Comments