▲ 0 r/selfhosted
One month into a custom Stremio addon stack and I can't tell anymore which of my decisions are clever vs cursed
Had a half-idle Hetzner box already running and got tired of paying monthly for a hosted streaming solution, so I went down the rabbit hole and built something custom around Stremio.
Stack ended up being:
- small Express addon handling the Stremio side (talks to the download client's API)
- indexer layer for source discovery
- download client for file management and storage
- Caddy for direct HTTPS on the streaming endpoint
- Cloudflare Tunnel for everything else
- Node proxy in front of the addon for invite-gated URLs (Telegram bot mints/revokes tokens through Telegraf)
Addon-side decisions I'm not sure about:
- Sequential download + first/last piece priority so playback starts almost immediately while the file is still being fetched. Works surprisingly well until the player's read head catches up to disk writes.
- Retention-policy watcher state currently lives in memory, so I had to add a startup hook that re-attaches policy enforcement to every active item after container restarts.
- Per-source retention rules with different thresholds depending on where the file originated.
- bingeGroup fallback so season packs still trigger auto-play next-episode behavior even when cached lookups return empty stream metadata.
- Nightly Trakt-trending → indexer → download client warm-cache job so popular stuff is usually already available before anyone asks for it.
Proxy-side decisions I'm less confident about:
- Proxy rewrites stream lists before Stremio sees them (filters by source quality, hides source names, rebrands addon output). Feels duct-tapey but functional.
- Per-token "allowed hash" cache so people can't bypass tier limits by constructing direct requests manually.
- Invite tokens persist to JSON with expiry windows; Telegram bot also lists/revokes.
- Oversized streams get rewritten to an external info page instead of triggering an actual fetch/play request.
Stuff that bit me embarrassingly hard:
- Spent hours debugging why unrelated media kept resolving to the same giant file. Turned out single-file sources at the root path were falling through a
dirname()edge case and returning the largest mkv in the library every time. - Some archives needed an automatic extraction step or the player would happily stream the sample file instead of the actual content.
- MKV index reads from the END of the file completely wreck naive byte-offset watch progress tracking.
- External player resume handling on Android Stremio still seems broken unless you use the internal player.
Mostly looking for feedback on:
- smarter ways to enforce per-user/tier limits at the proxy layer
- whether persisting watcher state is cleaner than rebuilding state on startup
- credential management for upstream sources once you go beyond "just me and 2 friends"
- any obvious architectural footguns before this thing turns into accidental infrastructure
Running stable for about a month now but I've stared at it too long to trust my own judgment anymore.
u/Either_Lifeguard_250 — 5 days ago