Viibestream is a self-hosted live streaming platform that runs entirely in the browser. Broadcast from your camera and mic — or share a video file — and viewers watch instantly over a WebSocket, with no plugins, native apps, or third-party services in the loop. You own the server, the stream, and the data.
Features
- Browser broadcasting from camera + mic, or share a video file straight from the browser
- Public viewer page with autoplay, mute/unmute, volume, fullscreen and a live viewer count
- "Now Showing" panel — title, description, IMDB link and poster, updated live for viewers
- Real-time chat with custom names and emoji avatars, replies, @-mentions and emoji reactions
- Voice talk-back — viewers can be heard via voice-activity detection, with multi-speaker mixing
- Moderation — per-person mute, "mute all", participant roster with speaking indicators, and IP bans
- Role-based access — admin / streamer / viewer, with a login-gated admin dashboard
- Hardened by default — bcrypt passwords, CSRF on every form, per-request CSP nonces, session hardening, login rate limiting and account lockout, optional Cloudflare Turnstile
Requirements
- Docker Engine 20.10+ and the Docker Compose v2 plugin
- A modern browser for broadcasting (camera/mic needs HTTPS or localhost)
Install with Docker Compose
Create docker-compose.yml using the published image:
services:
viibestream:
image: hyprlab/viibestream:latest
container_name: viibestream
restart: unless-stopped
env_file:
- .env
environment:
- FLASK_ENV=production
ports:
- "0.0.0.0:${PORT:-8080}:${INTERNAL_PORT:-8000}"
volumes:
- viibestream_data:/app/instance
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
volumes:
viibestream_data:
Grab the example env file and generate a secret key:
curl -fsSL https://raw.githubusercontent.com/hyprlab/viibestream/main/.env.example -o .env
python3 -c "import secrets; print(secrets.token_urlsafe(64))"
Set the essentials in .env, then launch:
SECRET_KEY=<paste-long-random-string>
INITIAL_ADMIN_USERNAME=admin
INITIAL_ADMIN_PASSWORD=<strong-one-time-password>
PUBLIC_ORIGIN=https://stream.example.com
docker compose pull
docker compose up -d
Open the public viewer at http://localhost:8080, sign in at /auth/login, change your password, then go live at /admin/stream. To build from source, clone the repo and run docker compose up --build -d.
Configuration
| Variable | Default | Purpose |
|---|---|---|
SECRET_KEY |
required | Signs session cookies and CSRF tokens |
INITIAL_ADMIN_PASSWORD |
— | One-time bootstrap password; blank it after first sign-in |
PUBLIC_ORIGIN |
http://localhost:8080 |
Allowed browser origin(s) for Socket.IO |
BEHIND_HTTPS_PROXY |
0 |
1 behind a TLS-terminating reverse proxy (recommended) |
TLS_ENABLE |
0 |
1 serves self-signed HTTPS on :8443 for LAN/demo |
PORT / INTERNAL_PORT |
8080 / 8000 |
Host port / container listen port |
Behind a reverse proxy, forward the WebSocket upgrade for /socket.io/* and send X-Forwarded-Proto: https.
Updating
docker compose pull
docker compose up -d
The SQLite database lives in the viibestream_data volume and survives restarts and rebuilds (only docker compose down -v deletes it).
Tech stack & license
Flask 3 · Flask-SocketIO · SQLAlchemy/SQLite · vanilla JS (MediaRecorder / MediaSource) · Gunicorn · Docker. Free and open source under the GNU AGPL-3.0. Full docs and releases on GitHub.