Sign inSign up

rebeliptv/iptv

By rebeliptv

Updated 1 day ago

Automatic M3U playlist and XML guide updater for IPTV clients with interactive web interface.

Image
6

10K+

rebeliptv/iptv repository overview

Rebel IPTV

Self-hosted IPTV server for live TV and sports

Docker Pulls Docker Image Size GitHub Release License Website Sponsor

Aggregates live TV channels and sports events into a single M3U playlist with full XMLTV guide data. Streams are fully proxied, so upstream sources are never exposed to your clients.

Built for Jellyfin, Emby and Plex, and any other app that takes an M3U playlist and an XMLTV guide. It can also answer as an HDHomeRun tuner, the path Plex and Emby build their Live TV around. The web dashboard is available in 19 languages.

🌐 New here? The setup guide at rebeliptv.com builds a Docker configuration for your system and walks you through connecting your player.

📖 Full documentation and screenshots: github.com/rebeliptv/iptv

Quick Start

Create a docker-compose.yml:

services:
    iptv:
        image: rebeliptv/iptv:latest
        container_name: iptv
        hostname: iptv          # lets clients on this compose network reach us by name
        ports:
            - "8080:8080"
        # All environment variables are OPTIONAL — the defaults work out of
        # the box. Uncomment any you need (see Configuration below):
        # environment:
        #     TZ: "America/New_York"   # set to YOUR timezone, e.g. Europe/London, America/Chicago, Etc/UTC
        #     HEADLESS: "true"         # no browser on this box — see Updating below
        volumes:
            - iptv-data:/app/data
            - /var/run/docker.sock:/var/run/docker.sock   # enables in-app updates
        stop_grace_period: 30s
        restart: unless-stopped

volumes:
    iptv-data:
docker compose up -d
Docker Run
docker run -d \
  --name iptv \
  -p 8080:8080 \
  -v iptv-data:/app/data \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --restart unless-stopped \
  rebeliptv/iptv:latest

# Environment variables are optional (defaults work). Add -e flags as needed, e.g.:
#   -e TZ=America/New_York   (set to YOUR timezone — e.g. Europe/London, Etc/UTC)

Then open the dashboard at http://<server-ip>:8080. A short setup wizard walks you through choosing a channel source, your local market, which channel countries to carry, live sports on or off, an optional playlist key and dashboard login, and copying your playlist and guide URLs into your player. You can skip it and change anything later in Settings.

About the Docker socket: the /var/run/docker.sock mount lets the container update itself from the dashboard. It also gives the container control of the Docker daemon on the host. If you'd rather not allow that, remove the line and update with docker pull instead (see Updating below).

Tags

TagUse it for
latestThe newest release. Required for the dashboard's Update now button and for headless mode.
<version>, e.g. 1.4.5Pinning a release. Update now is hidden on a pinned tag; change the tag and pull to upgrade.

Images are published for linux/amd64 and linux/arm64. What changed in each version: release notes.

Features

  • 450+ TV channels across the US, Canada and the UK, with logos and fixed channel numbers that never reshuffle
  • Live sports: NHL, NFL, NBA, MLB, MLS, CFL and college football games, plus fight cards and races, with live scores and stats and pregame/postgame guide entries
  • A channel for your favourite team that carries whichever game they're playing, home or away, and shows when they're next on the rest of the time
  • Your local ABC / CBS / NBC / FOX: your own market's affiliate for both the feed and the guide, never another city's station. The market defaults from your timezone; set it exactly in Settings → Content → Local Market
  • Custom M3U sources: merge your own playlists (by URL or upload), each with its own guide if it needs one
  • Your lineup, your way: enable, disable and drag-reorder channels, and choose which countries you carry
  • Rich guide data covering today and tomorrow, with descriptions, episode info, ratings and poster art, plus a timeline guide in the dashboard
  • Streams that recover: an on-server buffer rides out provider hiccups (add more in Settings → Playback), a failing source is swapped for a working one, and channels that go offline, or answer with no audio or video, are detected and recovered
  • Hosted feeds (optional): have your box pull ready-made channels, guide and events from Rebel IPTV instead of scraping sources itself, which also gets around regional blocks (Settings → Sources → Feed source)
  • One-click updates and restarts from the dashboard, and a headless mode that keeps itself up to date
  • Protected when you want it: an optional API key for the playlist and guide, an optional dashboard login with multiple admin accounts, and data encrypted at rest

TV, team and custom channels keep fixed numbers, so the mappings in your player survive restarts and upgrades:

NumbersChannels
1–3999TV channels
4000–4199Your favourite team channels
5000+Live sports events, numbered by start time on each refresh
10000+Your custom M3U sources, one range per source

Connecting Your Player

URL
M3U playlisthttp://<server-ip>:8080/playlist?key=YOUR_KEY
XMLTV guidehttp://<server-ip>:8080/epg?key=YOUR_KEY
XMLTV guide (gzip)http://<server-ip>:8080/epg.gz?key=YOUR_KEY

?key= is only needed once you've generated an API key (Settings → Access → Generate Key). Without one, the playlist and guide are open to anyone on your network.

Player running in a container on the same Docker network? A toggle in Settings switches the URLs you copy from the dashboard to the container's hostname (e.g. http://iptv:8080/playlist), so they work without hand-editing.

Jellyfin
  1. Dashboard → Live TV → Tuner Devices → Add, and choose M3U Tuner
  2. Enter the playlist URL. The guide URL is picked up from the playlist header
  3. Save and refresh guide data

Recommended tuner settings:

  • Auto-loop live streams: off. With it on, Jellyfin transcodes every channel instead of playing it directly, and the transcode falls behind and freezes the picture. The only trade-off: after a server restart or update, re-select the channel.
  • Allow fMP4 transcoding container: off. Allow stream sharing: on. Ignore DTS: on. Read input at native frame rate: on.

Jellyfin can also add the server as an HDHomeRun tuner (enter <server-ip>:8080), and the stream is identical. The M3U route is suggested because your playlist URL is protected by your API key and the tuner's endpoints can't be.

Plex & Emby

Both build their Live TV around HDHomeRun tuners, so the server answers as one. No Plex Pass is needed. Check that Settings → Connect → Act as an HDHomeRun tuner is on (it is by default).

  • Plex: Settings → Live TV & DVR → Set up Plex DVR. The server doesn't announce itself on your network, so click Don't see your HDHomeRun? and enter <server-ip>:8080. Skip the antenna lineup step, choose Have an XMLTV guide? and give it the guide URL, then check the channel mapping and save.
  • Emby: Live TV → Add tuner → HDHomeRun, enter <server-ip>:8080, then add the guide URL as an XMLTV guide source.

Important: the tuner's endpoints are not protected by your API key, because the HDHomeRun protocol has no way to carry one. Use it on a trusted or local network, not one exposed to the internet.

Simultaneous streams

Settings → Connect → Simultaneous streams (default 4, range 1–32) sets how many different channels play at once, across the tuner, the playlist and the dashboard. Several devices watching the same channel count as one. A channel past the limit shows a stream limit reached card and starts on its own as soon as another channel stops. Set it to what the line behind your channels can actually carry.

Configuration

All environment variables are optional.

VariableDefaultDescription
TZEtc/UTCYour timezone. Also picks the default local market for ABC / CBS / NBC / FOX (override it in Settings → Content → Local Market)
HEADLESSfalseFor boxes nobody opens a browser on. See Headless mode below
PORT8080Server port
HOST0.0.0.0Bind address
CRON_SCHEDULE30 * * * *Data refresh schedule (cron). Each server starts its refresh at its own fixed point up to 20 minutes after this
TRUSTED_PROXIES(none)Only behind a reverse proxy: its addresses or CIDR ranges, comma-separated. See Reverse proxy below
RESET_AUTHfalseLocked out of the dashboard? Set to true and restart to remove every dashboard login, then remove it again. While it is set, logins are cleared on every start

Sports, leagues, channel countries, local market, feed source, stream buffering and the tuner are dashboard settings, not environment variables.

Your data lives in the /app/data volume and survives restarts and upgrades. The database snapshot in it is encrypted at rest with AES-256-GCM.

Updating

From the dashboard: when a newer version exists, an Update now button appears on the Dashboard and in Settings → Server. Click it and the server downloads the new version and restarts, keeping your data. It needs the :latest tag and the Docker socket mount shown above. A server that falls too far behind to run shows a page saying so at its usual address, with the same button.

From the command line:

docker pull rebeliptv/iptv:latest
docker compose up -d

Your data lives in the iptv-data volume, so this only swaps in the new image.

docker restart is not an update. It starts the same container again on the same old image. docker compose up -d is what recreates it on the image you just pulled.

Headless mode: if nothing on the box has a browser (a NAS, a Kodi/LibreELEC box, a server you only reach over SSH), set HEADLESS=true. The server then checks for and installs new versions on its own, waiting until nothing is streaming so it never interrupts a viewer, and skips the first-run wizard so a fresh install needs no visit to the dashboard. It needs the Docker socket mount and the :latest tag.

Restarting: Settings → Server → Restart Server restarts on the same version with nothing lost, on any setup.

Reverse Proxy

The playlist and guide URLs are built from the Host header your proxy passes through, and switch to https when the proxy sends X-Forwarded-Proto: https, so forward the original Host. Set TRUSTED_PROXIES to your proxy's address so logs and the login rate limit see the real visitor instead of the proxy. Left unset, no proxy is trusted, which is the safe default.

Nginx

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Traefik

labels:
    - "traefik.enable=true"
    - "traefik.http.routers.iptv.rule=Host(`iptv.example.com`)"
    - "traefik.http.services.iptv.loadbalancer.server.port=8080"

Support

License

Proprietary: free for personal, non-commercial use, and only in its published container form. See the LICENSE for details.

Tag summary

Content type

Image

Digest

sha256:03deacb40

Size

17.8 MB

Last updated

1 day ago

docker pull rebeliptv/iptv