Skip to content

Repository files navigation

🎬 stremio-libtorrent-server

Your own Stremio streaming server β€” open, fast, and yours. One command to run it. πŸš€

Self-host the complete Stremio experience β€” the web player and a powerful, open BitTorrent streaming engine β€” in a single container on your own hardware. It's a full torrent client, not just a streamer: it downloads whole files and can pin favorites to keep & seed. Point any Stremio client (browser, Android TV, Tizen, webOS, desktop) at it and press play.

No subscription. No tracking. No black box. 100% free and open β€” our gift to the community. πŸ’›

Sharing back with the community. πŸ’› This is a real torrent client, so a title you started keeps downloading to completion and seeding (uploading) back to other Stremio users even after you close the player β€” that's how you help keep the swarm fast and healthy for everyone. Unpinned titles are cleared automatically; pin the ones you'd like to keep sharing. Prefer to limit it? Cap up/down bandwidth in the settings any time β€” your box, your call.

Docker Hub License: MIT


✨ Why you'll love it

  • πŸš€ Install in one command. docker run … β€” that's the whole setup. No building, no config files.
  • πŸ“Ί Just works on TVs. Automatic trusted HTTPS (a real Let's Encrypt cert) that smart TVs actually accept β€” zero certificate headaches.
  • ⚑ Faster, more reliable. Unlike the closed stock server, this one accepts inbound peers and fetches playhead-first, so streams start quicker and hold up on thin swarms.
  • πŸŽ›οΈ Truly yours to control. Real dials for cache, buffering, peers, and transcode β€” tune deeply, or never touch a thing.
  • πŸ–₯️ Hardware transcode, optional. Intel VAAPI / NVIDIA NVENC when you expose a GPU to the container (opt-in β€” see Advanced), with graceful CPU fallback β€” and a missing GPU never stops it from starting.
  • 🧩 Your addons, your choice. It's neutral infrastructure: it streams whatever a Stremio addon hands it. It bundles no content and is not a source.
  • πŸ”“ Open source. Read it, change it, trust it.

πŸš€ Quick Start β€” anyone can do this

Architecture: the published image is linux/amd64 (x86-64) only. It runs on any normal PC/server/NAS. ARM hosts (Raspberry Pi, most ARM TV boxes, Apple Silicon) aren't supported by the prebuilt image β€” build from source on those.

1. Install Docker. 2. Copy one command below β€” whichever matches your hardware β€” and replace YOUR_SERVER_IP with your machine's LAN IP (e.g. 192.168.1.50). Not sure which? Use the first one β€” it works on everything. (The GPU options only speed up the occasional video that needs converting; they're not required.)

πŸ’» No GPU β€” works everywhere (start here)

docker run -d --name stremio --restart unless-stopped \
  -e IPADDRESS=YOUR_SERVER_IP \
  -p 8080:8080 -p 12470:12470 -p 6881:6881/tcp -p 6881:6881/udp \
  -v stremio-data:/root/.stremio-server \
  androshack/stremio-libtorrent-server

🟦 Intel / AMD GPU (VAAPI) β€” same, plus --device /dev/dri

docker run -d --name stremio --restart unless-stopped \
  -e IPADDRESS=YOUR_SERVER_IP \
  --device /dev/dri:/dev/dri \
  -p 8080:8080 -p 12470:12470 -p 6881:6881/tcp -p 6881:6881/udp \
  -v stremio-data:/root/.stremio-server \
  androshack/stremio-libtorrent-server

🟩 NVIDIA GPU (NVENC) β€” plus --gpus all (first install the NVIDIA Container Toolkit on the host)

docker run -d --name stremio --restart unless-stopped \
  -e IPADDRESS=YOUR_SERVER_IP \
  --gpus all \
  -p 8080:8080 -p 12470:12470 -p 6881:6881/tcp -p 6881:6881/udp \
  -v stremio-data:/root/.stremio-server \
  androshack/stremio-libtorrent-server

🟦🟩 Both Intel + NVIDIA β€” both flags

docker run -d --name stremio --restart unless-stopped \
  -e IPADDRESS=YOUR_SERVER_IP \
  --gpus all --device /dev/dri:/dev/dri \
  -p 8080:8080 -p 12470:12470 -p 6881:6881/tcp -p 6881:6881/udp \
  -v stremio-data:/root/.stremio-server \
  androshack/stremio-libtorrent-server

3. Open it:

  • 🌐 In a browser (same network): http://YOUR_SERVER_IP:8080 β€” browser playback covers MP4/H.264; for MKV/HEVC content use the desktop or TV apps (browsers can't decode those).
  • πŸ”’ Trusted HTTPS (and TVs): run docker logs stremio and use the printed URL β€” it looks like https://192-168-1-50.519b6502d940.stremio.rocks:12470 (replace 192-168-1-50 with your internal IP, dots written as dashes).

Sign into Stremio, add your addons, press play. 🍿 (Prefer a file? Grab compose.hub.yaml β†’ IPADDRESS=YOUR_SERVER_IP docker compose -f compose.hub.yaml up -d.)


🧰 Minimum hardware

It's light β€” direct play (most content) barely touches the CPU; the GPU only matters for transcoding.

Resource Minimum Recommended Notes
CPU 2 cores, x86-64 4+ cores amd64 only. Transcoding (clients that can't direct-play) is the only heavy load.
RAM 1 GB 2 GB+ Engine + buffers + nginx; transcoding adds ~0.5–1 GB.
Disk ~3 GB + cache SSD, cache β‰₯ largest file Image ~1.5 GB; download cache defaults to 18 GiB (tune with STREMIOSRV_CACHE_SIZE). Keep free space β‰₯ your biggest single file.
GPU none Intel VAAPI / NVIDIA NVENC Optional β€” only speeds up transcoding; a missing/broken GPU never blocks startup.
Network any wired + 6881 forwarded Wired beats Wi-Fi for 4K; forward port 6881 for the full swarm (see below).

πŸ“Ί On your TV

Smart TVs insist on a trusted HTTPS connection β€” a self-signed cert won't do. Set IPADDRESS and this server fetches a real Let's Encrypt certificate for you automatically (via Stremio's *.stremio.rocks magic DNS, which maps that long URL back to your server's IP β€” even on your LAN). In the TV's Stremio app, set the Streaming Server URL to the …stremio.rocks:12470 address shown by docker logs stremio.

Note β€” the Stremio desktop app (v6). The desktop shell launches its own bundled streaming server and re‑points itself at 127.0.0.1:11470 on every start β€” it injects a ?streamingServerUrl= parameter that overwrites the saved URL β€” so simply setting the Streaming Server URL doesn't stick. (This is the shell's behaviour, not a serverVersion gate β€” that part is already correct.) Two ways to use this box from the desktop:

  • Best β€” launch with a flag (native player, full MKV/HEVC): start Stremio with --development --webui-url=<your …stremio.rocks:12470 URL> (the trusted URL from docker logs stremio). A non‑default --webui-url skips the localhost injection and loads the player from this box; --development also skips the unused bundled server. Add the flag to your shortcut and launch from it each time. It must be the trusted :12470 URL β€” a self‑signed cert is refused. After signing into your account, relaunch via the shortcut (login resets the URL).
  • Zero‑install (MP4/H.264 only): open the :12470 URL in a browser, or install it as an app.

TVs are unaffected β€” Samsung/LG accept the :12470 URL directly and it sticks.


🌍 Want the full swarm? Forward one port.

A lot of BitTorrent's speed comes from peers reaching you β€” and home routers block that by default. For maximum peers and throughput, forward port 6881 (TCP and UDP) on your router to your server. It works fine without forwarding β€” you'll just reach fewer peers on sparse torrents. (Unlike the stock server, this one actually listens for inbound peers, so the forward genuinely pays off.)


πŸ” Run behind a VPN

Tunnel only the streaming server's BitTorrent traffic through a VPN (kill-switch + optional port-forwarding) using gluetun, while your LAN keeps reaching the player/admin directly:

WIREGUARD_PRIVATE_KEY=... WIREGUARD_ADDRESSES=10.2.0.2/32 IPADDRESS=<your-LAN-IP> \
  docker compose -f compose.vpn.yaml up -d

Notes:

  • The VPN's kill-switch is on by default β€” if the tunnel drops, torrent traffic stops (no IP leak).
  • Inbound peers / seeding need a provider that supports port-forwarding (e.g. ProtonVPN, PIA, AirVPN). Without it you still stream, but with outbound-only connectivity.
  • Set FIREWALL_OUTBOUND_SUBNETS to your LAN CIDR(s) so the player and admin stay reachable.

πŸ”§ Advanced β€” tune it your way

Everything is a plain -e NAME=value environment variable:

Setting Default What it does
IPADDRESS (unset) Your server IP β†’ auto trusted TV cert via *.stremio.rocks. Unset β†’ self-signed.
SERVER_URL auto URL the web player targets. Set for a custom domain.
STREMIOSRV_CACHE_SIZE 19327352832 (18 GiB) Download-cache budget in bytes (LRU-evicted). Keep it above your largest file.
STREMIOSRV_READAHEAD_BYTES 134217728 (128 MiB) Playhead buffer β€” bigger absorbs more swarm jitter (fewer rebuffers).
STREMIOSRV_BT_LISTEN_PORT 6881 BitTorrent peer port (TCP and UDP, IPv4 and IPv6). The one to forward. If you change it, publish the same port β€” the compose files and docker/launch.sh follow this var automatically; a hand-rolled docker run must use matching -p <port>:<port>/tcp -p <port>:<port>/udp (mapping to a different container port silently kills inbound peering).
STREMIOSRV_BT_MAX_CONNECTIONS 400 Max peer connections.
STREMIOSRV_DOWNLOAD_RATE_LIMIT 0 Cap download throughput in bytes/sec (0 = unlimited). E.g. 12500000 β‰ˆ 100 Mbit/s.
STREMIOSRV_UPLOAD_RATE_LIMIT 0 Cap upload throughput in bytes/sec (0 = unlimited). Handy so seeding doesn't saturate your line.
STREMIOSRV_IDLE_DOWNLOAD_RATE_LIMIT 1048576 (1 MiB/s) Cross-torrent playback priority. While anything is being streamed, every other (idle) torrent is capped to this many bytes/sec so the torrent you're watching wins the bandwidth. 0 disables it (idle torrents compete freely).
STREMIOSRV_MAX_STREAMS 0 Max concurrent playbacks (distinct torrents being streamed). A new play past the cap gets 503. 0 = unlimited.
STREMIOSRV_SEED_ON_COMPLETE true Keep seeding after a torrent finishes (full torrent-client behaviour). false = stop seeding + drop peers the moment it completes. Pinned items always keep seeding.
STREMIOSRV_MAX_SEED_MINUTES 0 Stop seeding this many minutes after completion (0 = seed forever). Applies on top of SEED_ON_COMPLETE.
STREMIOSRV_EXTRA_TRACKERS (empty) Extra trackers appended to every torrent (on top of the built-in defaults). Comma/space/newline-separated udp:///http(s):///ws(s):// URLs.
STREMIOSRV_TRACKER_LIST_URL (empty) Optional URL of a community tracker list (e.g. the raw ngosang/trackerslist trackers_best.txt). Fetched in a background thread to keep the list current β€” best-effort, never blocks startup or playback; offline falls back to the last cached list, then the built-in defaults. Empty = fully static.
STREMIOSRV_TRACKER_LIST_REFRESH_HOURS 24 How often the background tracker-list source re-fetches (only when a URL is set).
STREMIOSRV_ADAPTIVE_PICKING false Experimental. While playing, relax strict sequential download to parallel once enough is buffered ahead of the playhead (harvests more swarm throughput), re-tightening to in-order when the buffer drains or on a seek β€” the playhead window stays deadline-rushed, so continuity is protected. Off by default; needs on-box tuning.
DOMAIN localhost CN for the self-signed cert (when not using IPADDRESS).
CERT_FILE certificates.pem Bring-your-own cert (full-chain + key) filename in the data volume.

Trackers & peer discovery. Every torrent is announced to a curated set of public trackers (baked-in defaults) plus DHT, LSD and PEX β€” so a bare infohash finds peers even when the magnet carries no tracker, exactly like the stock Stremio server. Extend it two ways: add your own with STREMIOSRV_EXTRA_TRACKERS, or point STREMIOSRV_TRACKER_LIST_URL at a maintained list (e.g. ngosang/trackerslist) to keep the set current β€” that fetch runs in a background thread and never blocks startup or playback (offline β†’ last cached list β†’ the built-in defaults). The bigger peering win, though, is inbound connectivity: forward STREMIOSRV_BT_LISTEN_PORT (6881) so you reach the whole swarm, not just what trackers hand back.

GPU transcode (only for clients that can't direct-play). Docker does not expose the host GPU to a container by default, so the one-command install above is CPU-only. The server auto-detects a GPU, but only one you've handed in β€” so opt in at launch:

  • Intel/AMD VAAPI β†’ add --device /dev/dri:/dev/dri
  • NVIDIA NVENC β†’ add --gpus all (requires the NVIDIA Container Toolkit on the host)
  • Or just use docker/launch.sh β€” it probes the host and adds the right flags for you, degrading gracefully (a broken or absent driver never blocks startup). Full NVIDIA driver + Proxmox passthrough setup: NVIDIA-GPU.md (companion fork).

Your own domain instead of stremio.rocks: put a full-chain+key PEM as certificates.pem in the data volume, set -e SERVER_URL=https://yourdomain:12470, and leave IPADDRESS unset.

Tailscale (zero port-forwarding, trusted HTTPS): if you reach the server over a Tailscale tailnet, you can skip both port-forwarding and the *.stremio.rocks dependency. Provision a cert for the node's MagicDNS name (tailscale cert <node>.<tailnet>.ts.net), concatenate the cert + key into one PEM, drop it in the data volume as certificates.pem, and set -e SERVER_URL=https://<node>.<tailnet>.ts.net:12470 with IPADDRESS unset. Point your devices' Stremio Streaming Server URL at that tailnet address β€” works across your own devices and anyone you share the tailnet with, with a browser/TV-trusted cert.

Ports: 8080 web+API (HTTP/LAN) Β· 12470 web+API (HTTPS) Β· 11470 direct API Β· 6881 BitTorrent.

πŸ“– Full ops guide: docs/DEVOPS.md Β· TLS deep-dive: docs/cert-guide.md.


🧠 Why it exists

The stock Stremio streaming server is closed-source and, in practice:

  • outbound-only β€” it never listens for inbound peers, so you only reach the connectable half of a swarm;
  • it hides the torrent levers β€” no real control over piece picking, connectivity, or cache.

This opens it up: inbound connectivity + playhead-first piece picking for faster starts and better reliability on sparse swarms, plus hardware transcode for clients that can't direct-play β€” all in an image you run yourself. It is content-neutral infrastructure: it streams whatever infohash a Stremio addon hands it, and bundles or surfaces nothing.

πŸ—οΈ Under the hood

One image, two source repos. The runtime image is built FROM a GPU/ffmpeg base (the companion fork) and layers the open server on top:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ stremio-docker-dual  (companion fork, MIT) ──────────────┐
β”‚ jellyfin-ffmpeg (NVENC/VAAPI) Β· nginx Β· bundled Stremio web player        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚ FROM
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ stremio-libtorrent-server  (this repo) ──────────────────┐
β”‚ FastAPI + libtorrent engine Β· nginx serves web player + proxies the API   β”‚
β”‚ β†’ one container: web player + open engine on a single origin              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Companion fork: andrewhack/stremio-docker (builds the stremio-docker-dual image; see its NVIDIA-GPU.md for GPU/Proxmox setup).

Modules: api/ (Stremio HTTP API) Β· torrent/ (libtorrent + piece-picker) Β· stream/ (Range file server) Β· transcode/ (ffmpeg NVENC/VAAPI β†’ HLS) Β· config.py Β· health.py. Protocol reference: docs/protocol-map.md.

βœ… Status

All stages shipped and verified on hardware:

Stage Scope State
0–1 Protocol map Β· FastAPI skeleton Β· /health βœ…
2 Torrent core + direct play (inbound peers, head & holes, Range serving, stats) βœ…
3 Transcode / HLS (hlsv2, NVENC/VAAPI) βœ…
4 Subtitles Β· opensubHash Β· casting βœ…
5 Productionise β€” compose, DEVOPS, healthcheck, AHM βœ…
6 All-in-one (web player + engine) Β· TV-trusted SSL Β· GPU-optional Β· Docker Hub βœ…

πŸ› οΈ Development

uv sync
uv run pytest -q          # unit tests
uv run ruff check .       # lint
uv run uvicorn stremiosrv.app:create_app --factory --host 0.0.0.0 --port 11470

πŸ” Appendix β€” how the TV HTTPS URL works (*.stremio.rocks)

Skip this unless you're curious or customizing certs β€” the Quick Start needs none of it.

When you set IPADDRESS, the container prints a TV-ready HTTPS URL like:

https://192-168-1-50.519b6502d940.stremio.rocks:12470
        β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”¬β”€β”˜
          your IP,     shared ID     Stremio's    HTTPS
          dashed       (see below)   free DNS     port
  • 192-168-1-50 β€” your server's IP with dots turned into dashes.
  • …stremio.rocks β€” a free service Stremio runs that (a) resolves <dashed-ip>.…stremio.rocks back to that IP (even a LAN IP β€” no DNS setup by you), and (b) carries a trusted Let's Encrypt wildcard cert, so TVs/browsers accept the HTTPS connection with no warning.
  • :12470 β€” the container's HTTPS port.

A TV opening it β†’ resolves to your server's IP β†’ connects on 12470 β†’ sees a trusted cert β†’ connects. The name resolves to your internal IP, so the TV must be on the same network (normal home setup). For remote access, use your public IP in the URL and forward port 12470.

About 519b6502d940 β€” a shared, third-party dependency

This ID belongs to Stremio's own certificate service, not to any docker image: the cert is fetched from Stremio's API (api.strem.io/api/certificateGet), which issues it for a subdomain of Stremio's stremio.rocks domain. It is not unique to your install β€” everyone running this (or the upstream tsaridas/stremio-docker) image shares the same *.519b6502d940.stremio.rocks wildcard cert from Stremio's free certificate service. The image only calls that Stremio API; it didn't create the ID.

  • βœ… Zero-config trusted HTTPS for TVs.
  • ⚠️ It depends on Stremio's cert service keeping that wildcard alive; if it's ever rotated or taken down, the automatic cert path stops working (your stream still runs β€” only the trusted-HTTPS URL is affected).

Independent fallback β€” bring your own cert (no reliance on stremio.rocks): put a full-chain + key PEM as certificates.pem in the data volume, set -e SERVER_URL=https://yourdomain:12470, and leave IPADDRESS unset β€” the server uses your cert as-is. Or, on a trusted LAN, skip HTTPS entirely and use http://<your-server-ip>:8080.

πŸ“œ License & spirit

MIT β€” built on the MIT-licensed stremio-docker fork.

This is not a commercial product, and we don't monetize it. It's our contribution to the people who just want their own open, private streaming server. Use it, share it, make it better. πŸ’›

Keep it legal: this is neutral infrastructure for content you have the right to stream.

About

Self-hosted Stremio: open libtorrent engine + web player, one container - One-command installation

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages