I got tired of installing yet another IPTV app on every screen in the house — phone, tablet, TV box, laptop — and none of them felt the same. So I built Streamly, a browser-based IPTV web player you can run yourself. No app store. No weird APK sideload. Just a URL.
If you already have an Xtream login or an M3U playlist from your provider, self-hosting Streamly gives you a single, calm interface for live TV, movies, and series. This post is the Docker setup I actually run — not theory, not a vendor doc rewrite.
Why self-host an IPTV web player at all?
Hosted SaaS players are fine until they aren't: domain changes, ads, feature churn, or privacy questions about where your playlist credentials live. A self-hosted IPTV player lives on your machine or VPS. You control updates, backups, and who can reach it.
Streamly is MIT-licensed and on GitHub. I use it because I wanted something that loads fast in Safari, doesn't look like a 2012 Kodi skin, and treats Xtream Codes as a first-class citizen — not an afterthought next to a janky M3U import.
What you need before Docker
- Docker and Docker Compose on a Linux box, NAS, or home server (2 GB RAM is plenty for a household).
- Your own Xtream portal URL + username + password, or an M3U / M3U8 URL from your provider. Streamly does not sell or supply streams.
- A domain (optional but nice) with HTTPS — Caddy, Traefik, or nginx on the host in front of port 3000.
My docker-compose.yml (the short version)
Clone the repo, copy .env.example to .env, and fill in secrets. The compose file in the repo looks like this:
services:
streamly:
build: .
ports:
- "3000:3000"
volumes:
- streamly_data:/app/data
environment:
AUTH_SECRET: ${AUTH_SECRET}
STREAM_SESSION_SECRET: ${STREAM_SESSION_SECRET}
DATABASE_URL: file:/app/data/stream.db
volumes:
streamly_data:The important bit is the streamly_datavolume. That's where SQLite lives — accounts, favorites, watch progress. Blow away the container without the volume and you'll wonder where your settings went. (Ask me how I know.)
Step-by-step: first boot
git clone https://github.com/kvnpyy/streamly.gitandcd streamly(or whatever you named the folder).- Generate secrets:
openssl rand -base64 32— use one output forAUTH_SECRETand another forSTREAM_SESSION_SECRET. - Set
NEXT_PUBLIC_SITE_URLto your public URL (e.g.https://tv.yourdomain.com) so canonical links and the sitemap are correct. docker compose up -d --build— first build takes a few minutes; after that it's cached.- Open
http://your-server:3000, create a Streamly account if you want cloud sync for favorites, then sign in with your Xtream or M3U credentials.
Environment variables I actually set
AUTH_SECRET— required for Stream account sign-in (Auth.js).STREAM_SESSION_SECRET— encrypts the HttpOnly session that holds your IPTV login between page loads.DATABASE_URL— keep the defaultfile:/app/data/stream.dbinside the volume.RESEND_API_KEY+EMAIL_FROM— only if you want email verification and password reset on your instance.TMDB_API_TOKEN— optional; nicer posters on live channels when EPG titles match.
I leave NEXT_PUBLIC_GA_MEASUREMENT_ID empty on self-hosted installs. No analytics phone-home on a box I own.
Updates and backups
To update: git pull, then docker compose up -d --build. Your data volume survives. For backups, copy /app/data/stream.db from the volume (or use the npm run db:backup script on a dev checkout). I do this weekly to a boring old folder on my NAS.
Who is this for?
Homelab folks, expats sharing one server with family, anyone who already pays for IPTV and wants a clean self-hosted IPTV player instead of fifteen different apps. It's not a magic wand — you still need a lawful subscription from your provider.
Try it without Docker first
Not ready to host? The public instance at iptvwebplayer.org runs the same codebase. Same player, zero Docker. When you outgrow it, your compose file is waiting.
If something breaks in your setup, open an issue on GitHubwith your browser, proxy, and whether you're on Xtream or M3U — I read them.
Disclaimer: Streamly is a media player only. It does not provide channels, playlists, or copyrighted content. You are responsible for your provider subscription and compliance with local law.