Docker proxy that gives a Dispatcharr M3U account several provider URLs and fails over between them
569
A small proxy that gives a Dispatcharr M3U account several provider URLs.
Dispatcharr stores one server URL per account. This proxy gives each account a local port and forwards every request to the first working URL on that account's list. It is one Python file with no dependencies.
Docker image: brxdy22/m3u-failover (amd64 and arm64).
upstreams.conf. URLs are never removed.Tested on Dispatcharr 0.33.0.
Works with Failover Manager and Gluetun AutoSwitch. All three together cover provider URL failover, account failover for VOD, and VPN exit switching.
See Dispatcharr Failover Stack to install all three side by side.
upstreams.conf.example into it as upstreams.conf. Add your URLs.docker-compose.example.yml to your Compose file. Set network_mode to match your setup, and the volume to your config folder.docker compose up -d m3u-failover.http://127.0.0.1:<port>, using the port from upstreams.conf.The examples use brxdy22/m3u-failover:latest. To update, pull the image and start the container again: docker compose pull m3u-failover && docker compose up -d m3u-failover. Each release also has a version tag, for example brxdy22/m3u-failover:1.3.1.1, if you prefer to pin one.
To run it without the image, mount failover.py into python:3.12-alpine at /app/failover.py and use command: ["python", "-u", "/app/failover.py"].
Usernames and passwords stay in Dispatcharr. The proxy holds them in memory for the nightly sort, and never logs or saves them.
# Table of accounts, URLs and current streams
docker exec m3u-failover python /app/failover.py --status
# Run the sort now
docker exec m3u-failover python /app/failover.py --sort-now
An account is skipped by the sort until Dispatcharr has sent a request through the proxy since it started.
Set these as environment variables. The full list is at the top of failover.py.
| Variable | Default | Meaning |
|---|---|---|
CONNECT_TIMEOUT | 8 | Seconds to connect before trying the next URL |
HEADER_TIMEOUT | 60 | Seconds to wait for headers before trying the next URL |
COOLDOWN_SECONDS | 300 | How long a failed URL is tried last |
FAILOVER_STATUSES | 403,500,502,503,504,520-530 | Answers that move on to the next URL |
MAX_ATTEMPTS | 4 | Most URLs tried per request |
BREAKER_SECONDS | 60 | First pause after everything fails |
API_RETRY_STATUSES | 404 | player_api.php answers that are tried again on the next URL |
API_RETRIES | 2 | Most extra URLs tried for one API call |
API_RETRY_DELAY | 2 | Seconds to wait before that retry |
SORT_AT | 03:00 | Time of the nightly sort, or off |
BIND | 127.0.0.1 | Address the proxy listens on |
EXIT_HOOK_URL | http://127.0.0.1:9733/vod-blocked | Where to ask Gluetun AutoSwitch to move a refused exit, or off |
REQUEST_DEADLINE_SECONDS | 9 | Most time a VOD request may take, including an exit move. Keep it below Dispatcharr's 10 s read timeout |
CANARIES | 2 | Titles that played before, asked to tell a refused exit from a missing title |
CANARY_FILE | vod_canaries.json next to upstreams.conf | Where those titles are kept: type and file name only, never the login |
SORT_USER_AGENT | m3u-failover | User agent for the nightly sort. Change it if a provider refuses these logins |
GET /__drop_live on an account's port closes its live streams at once, so clients reconnect right after a VPN exit change instead of waiting for a read timeout. Gluetun AutoSwitch calls it after every switch.
GET /__before_move?hold=N on an account's port closes all its streams, VOD included, and holds new requests for up to 6 seconds while the exit moves. /__drop_live ends the hold early. Gluetun AutoSwitch 1.8.2 calls it just before every switch.
GET /__status shows stuck_slot_seconds for an account whose provider keeps answering with a connection limit (458 or 460) while nothing is streaming. During that time the proxy answers repeat requests itself, so the provider sees about one try every 15 seconds.
POST /__urls with {"urls": [...]} on an account's port replaces that account's URLs in upstreams.conf and uses them at once. Notes on URLs that stay are kept. It is accepted only from loopback, and only base URLs (scheme://host[:port]) without logins. The Failover Manager plugin 1.5 uses it to show and edit the lists from Dispatcharr. GET /__status lists the full URLs under urls.
GET /__vod_check asks the remembered titles for one byte and answers whether the exit is refused. Gluetun AutoSwitch calls it in the background while nobody is watching. Add ?forget=1 to also forget titles that were refused.
The proxy has no login of its own, so keep BIND on 127.0.0.1 unless you trust everything that can reach it.
Keep upstreams.conf out of Git. It is already in .gitignore.
See Releases.
MIT
Content type
Image
Digest
sha256:098f5c6c1…
Size
17.2 MB
Last updated
3 days ago
docker pull brxdy22/m3u-failover