All apps · 0 apps
buffarr
Docker app from Uirel's Repository
Overview
Readme
View on GitHubbuffarr
buffarr combines prefetcharr and unmonitarr into a single service with full feature parity with both:
- prefetch -- watches what's playing on Jellyfin, Emby, Plex, or Tautulli and asks Sonarr to grab the next episodes of the show before you catch up to them.
- unmonitor -- keeps Sonarr/Radarr from grabbing fake pre-release files by unmonitoring content until its air/release date (plus a configurable delay) has actually passed, then re-monitoring it automatically.
Both features share a single Sonarr connection (SONARR_URL /
SONARR_API_KEY) and run in one process, one container, one config.
Why combine them?
If you run Sonarr/Radarr behind public indexers, unmonitor keeps you from grabbing fake pre-release junk. If you also stream from Jellyfin/Emby/Plex, prefetch keeps the next few episodes of whatever you're watching ready to go before you get there. They're complementary and commonly run side by side -- buffarr just runs them as one service instead of two.
Quick start
cp .env.example .env
# edit .env with your Sonarr/Radarr/media-server details
docker compose up -d
Or run locally:
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # edit it
./run_local.sh
Unraid
A Community Applications template is at
unraid/buffarr.xml. To install:
- In the Unraid Docker tab, click Add Container, switch to advanced
view, and set Template repositories to
https://raw.githubusercontent.com/Poag/buffarr/main/unraid/buffarr.xml-- or install Community Applications and search for "buffarr" once the template is submitted there. - Fill in
SONARR_URL/SONARR_API_KEYand, if you want prefetch too,ENABLE_PREFETCH+ theMEDIA_SERVER_*fields. Everything else has a working default -- click Show more settings for the rest (Radarr, delay/retention windows, tags, prefetch tuning). - The
/configpath maps to a single appdata folder containingconf/config.toml(optional -- seeconfig.example.toml, an alternative to filling in every field individually) andlogs/(rotating log files, written automatically).
The image runs as uid 99 / gid 100, matching Unraid's own nobody:users
convention, so a freshly created appdata folder is writable without any
permission fixing.
How it works
unmonitor
Runs on a schedule (SLEEP_MINUTES) and on webhook triggers from Sonarr/
Radarr (POST /trigger/sonarr, POST /trigger/radarr). For each tracked
item:
- Before its air/release date +
DELAY_MINUTES, it's unmonitored and tagged withAUTO_TAG_NAME-- Sonarr/Radarr won't search for it. - After the threshold passes, it's re-monitored (only if buffarr itself
unmonitored it, and only within
SONARR_REMONITOR_WINDOW_DAYS/RADARR_REMONITOR_WINDOW_DAYSof the air/release date) and the tag is removed. - Items tagged
IGNORE_TAG_NAMEare never touched. - A per-item
delayby_<N>tag (e.g.delayby_-60) overridesDELAY_MINUTESfor that series/movie. - Sonarr's
SEASON_PACK_MODEre-monitors an entire season at once (for shows taggedSEASON_PACK_MODE_TAG) once the first episode's threshold passes, instead of episode-by-episode. DRY_RUN=1(the default) logs every action without writing anything.
Configure Sonarr/Radarr webhooks to POST http://buffarr:5099/trigger/sonarr
and .../trigger/radarr on "On Series/Movie Add" for instant processing
instead of waiting for the next scheduled pass.
prefetch
Polls your media server every PREFETCH_INTERVAL seconds for active
playback sessions. For each TV episode being watched:
- Checks whether the next
PREFETCH_NUMepisodes are available in Sonarr. - If any are missing, searches for them -- as a season pack
(
PREFETCH_REQUEST_SEASONS=1, the default) when the season has fully aired, otherwise episode-by-episode. - If fewer than
PREFETCH_NUMepisodes are announced at all, monitors the series for new seasons/episodes instead of searching. PREFETCH_CHECK_AIRED=1skips episodes whose Sonarr air date is still in the future.PREFETCH_EXCLUDE_TAGskips prefetching for series carrying that Sonarr tag.MEDIA_SERVER_USERS/MEDIA_SERVER_LIBRARIESrestrict which sessions are watched.PREFETCH_APPEND_TO_QUEUE=1(Jellyfin/Emby/Plex only, experimental) also appends the newly-available episodes to the player's active queue.
Configuration
Configuration is via environment variables (see .env.example for a
complete annotated list) or, as an alternative, a TOML config file (see
config.example.toml). Highlights:
Using a config file instead of environment variables
Point buffarr at a TOML file instead of setting each variable individually, using whichever of these is most convenient:
A config directory (recommended for Docker). Mount one volume laid out as:
/config
├── conf/
│ └── config.toml # or buffarr.toml -- see config.example.toml
└── logs/ # rotating buffarr.log written here automatically
BUFFARR_CONFIG_DIR=/config python src/main.py
# or
python src/main.py --config /config
The Docker image already defaults BUFFARR_CONFIG_DIR to /config, so with
Docker all you need is -v /host/path:/config (or the volumes: line in
docker-compose.yml) -- no environment variable required.
Mounting a whole directory (rather than bind-mounting a single file) means
the file inside it can be added, edited, or renamed on the host without
touching the container's mount config, and Docker won't silently create an
empty directory if a bind-mounted file doesn't exist yet at container-create
time. conf/config.toml is optional -- set BUFFARR_CONFIG_DIR for the
logs/ output alone and keep using environment variables for everything
else if you'd rather.
A single file, or inline TOML text:
# a specific file (no logs/ output this way)
python src/main.py --config config.toml
# or equivalently
BUFFARR_CONFIG_FILE=/path/to/config.toml python src/main.py
# or the TOML text inline, handy for docker-compose without a volume mount
BUFFARR_CONFIG='
[prefetch]
ENABLE_PREFETCH = true
MEDIA_SERVER_URL = "http://jellyfin:8096"
' python src/main.py
The Docker image ships the sample file too, at /app/config.example.toml, so
you can pull a starting point out of it without cloning the repo:
docker run --rm ghcr.io/poag/buffarr:latest cat /app/config.example.toml > config.toml
Keys in the file must match the environment variable names below exactly
(case-insensitive); [section] tables are purely for readability and don't
affect anything. A real environment variable that is also set always wins
over the same key in the file, so you can mix both -- e.g. keep most
settings in conf/config.toml and pass a secret like SONARR_API_KEY as a
regular environment variable.
General
| Variable | Default | Description |
|---|---|---|
TZ |
UTC |
Timezone for date calculations |
LOG_LEVEL |
INFO |
DEBUG, INFO, WARNING, ERROR |
DRY_RUN |
1 |
unmonitor: 1 = log only, 0 = apply changes |
WEBHOOK_PORT |
5099 |
Webhook + health-check server port |
unmonitor
| Variable | Default | Description |
|---|---|---|
SLEEP_MINUTES |
30 |
Minutes between scheduled unmonitor passes |
DELAY_MINUTES |
120 |
Minutes after air/release before re-monitoring (can be negative) |
SKIP_IF_FILE |
1 |
Skip items that already have a file |
AUTO_TAG_NAME |
auto-unmonitored |
Tag applied to items buffarr unmonitored |
IGNORE_TAG_NAME |
ignore |
Tag that excludes an item from unmonitor entirely |
ENABLE_RADARR |
1 |
Enable Radarr unmonitor |
RADARR_URL / RADARR_API_KEY |
Radarr connection | |
PREFERRED_RELEASE |
either |
either, digital, or physical |
IGNORE_INCINEMAS |
0 |
Ignore cinema release dates |
RADARR_REMONITOR_WINDOW_DAYS |
30 |
Only re-monitor movies released within N days (0 = unlimited) |
ENABLE_SONARR |
1 |
Enable Sonarr unmonitor |
SONARR_URL / SONARR_API_KEY |
Sonarr connection (shared with prefetch) | |
SEASON_PACK_MODE |
0 |
Re-monitor whole seasons at once |
SEASON_PACK_MODE_TAG |
season-pack |
Tag marking series that use season-pack mode |
SONARR_REMONITOR_WINDOW_DAYS |
14 |
Only re-monitor episodes aired within N days (0 = unlimited) |
Per-item overrides: tag a series/movie with delayby_<N> (e.g.
delayby_-30) to override DELAY_MINUTES just for that item.
prefetch
| Variable | Default | Description |
|---|---|---|
ENABLE_PREFETCH |
0 |
Enable the prefetch feature |
MEDIA_SERVER_TYPE |
jellyfin |
jellyfin, emby, plex, or tautulli |
MEDIA_SERVER_URL / MEDIA_SERVER_API_KEY |
Media server connection (Plex: server token; Tautulli: API key) | |
MEDIA_SERVER_USERS |
(all) | Comma-separated user IDs/names to watch |
MEDIA_SERVER_LIBRARIES |
(all) | Comma-separated library names to watch |
PREFETCH_INTERVAL |
900 |
Polling interval in seconds |
PREFETCH_NUM |
2 |
Episodes to keep available in advance |
PREFETCH_REQUEST_SEASONS |
1 |
Prefer season-pack searches over per-episode |
PREFETCH_APPEND_TO_QUEUE |
0 |
Append prefetched episodes to the player's queue (Jellyfin/Emby/Plex only) |
PREFETCH_CHECK_AIRED |
0 |
Skip episodes that haven't aired yet |
PREFETCH_CONNECTION_RETRIES |
6 |
Retries when initially connecting to Sonarr/media server |
PREFETCH_EXCLUDE_TAG |
(none) | Sonarr tag that excludes a series from prefetching |
API keys
- Sonarr / Radarr:
Settings -> General -> Security - Jellyfin:
Administration -> Dashboard -> Advanced -> Api Keys - Emby: gear icon ->
Advanced -> Api Keys - Plex: extract the server token
- Tautulli:
Settings -> Web Interface -> API
Migrating from prefetcharr or unmonitarr
- If you only used unmonitarr, your existing environment variables work
unchanged (
SLEEP_MINUTES,DELAY_MINUTES,RADARR_*,SONARR_*,AUTO_TAG_NAME, etc. are all identical). Just setENABLE_PREFETCH=0(the default) and nothing else changes. - If you only used prefetcharr, set
ENABLE_PREFETCH=1and translate your TOML config to theMEDIA_SERVER_*/PREFETCH_*environment variables above (see.env.example).ENABLE_SONARR/ENABLE_RADARRdefault to1, so also setDRY_RUN=1(or configure unmonitor's thresholds deliberately) if you don't want the unmonitor feature acting on your library too.
Development
pip install -r requirements-dev.txt
PYTHONPATH=src pytest
License
MIT. See LICENSE and ATTRIBUTION.md.
Install Buffarr on Unraid in a few clicks.
Find Buffarr in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/poag/buffarr:mainRuntime arguments
- Network
bridge- Privileged
- false
Template configuration
Webhook trigger (/trigger/sonarr, /trigger/radarr) and health-check (/health) HTTP server.
- Target
- 5099
- Default
- 5099
- Value
- 5099
conf/config.toml (optional, see config.example.toml) and logs/ (rotating buffarr.log) live here.
- Target
- /config
- Default
- /mnt/user/appdata/buffarr
- Value
- /mnt/user/appdata/buffarr
Timezone for date calculations, e.g. Europe/London.
- Default
- UTC
- Value
- UTC
unmonitor: 1 = log actions only, 0 = apply them. Start at 1 to check the logs before going live.
- Default
- 1
- Value
- 1
unmonitor: manage Sonarr episode monitoring (1=yes, 0=no).
- Default
- 1
- Value
- 1
Sonarr base URL, e.g. http://10.0.0.2:8989 -- shared by unmonitor and prefetch.
Sonarr API key (Settings -> General -> Security).
unmonitor: manage Radarr movie monitoring (1=yes, 0=no).
- Default
- 1
- Value
- 1
Radarr base URL, e.g. http://10.0.0.2:7878.
Radarr API key (Settings -> General -> Security).
Enable the prefetch feature (predictive episode fetching from a media server). Requires SONARR_URL/SONARR_API_KEY and the MEDIA_SERVER_* fields below.
- Default
- 0
- Value
- 0
jellyfin, emby, plex, or tautulli.
- Default
- jellyfin
- Value
- jellyfin
Media server base URL, e.g. http://10.0.0.2:8096.
Jellyfin/Emby/Tautulli API key, or Plex server token.
unmonitor: minutes between scheduled passes.
- Default
- 30
- Value
- 30
unmonitor: minutes after air/release before re-monitoring (can be negative).
- Default
- 120
- Value
- 120
unmonitor: skip items that already have a file (1=yes, 0=no).
- Default
- 1
- Value
- 1
unmonitor: tag applied to items buffarr unmonitored.
- Default
- auto-unmonitored
- Value
- auto-unmonitored
unmonitor: tag that excludes an item from management entirely.
- Default
- ignore
- Value
- ignore
unmonitor/Radarr: either, digital, or physical.
- Default
- either
- Value
- either
unmonitor/Radarr: ignore cinema release dates (1=yes, 0=no).
- Default
- 0
- Value
- 0
unmonitor/Radarr: only re-monitor movies released within N days (0=unlimited).
- Default
- 30
- Value
- 30
unmonitor/Sonarr: only re-monitor episodes aired within N days (0=unlimited).
- Default
- 14
- Value
- 14
unmonitor/Sonarr: re-monitor whole seasons at once instead of episode-by-episode (1=yes, 0=no).
- Default
- 0
- Value
- 0
unmonitor/Sonarr: tag marking series that use season-pack mode.
- Default
- season-pack
- Value
- season-pack
prefetch: comma-separated user IDs/names to watch (default: all).
prefetch: comma-separated library names to watch (default: all), e.g. TV Shows.
prefetch: polling interval in seconds.
- Default
- 900
- Value
- 900
prefetch: episodes to keep available in advance.
- Default
- 2
- Value
- 2
prefetch: prefer season-pack searches over per-episode (1=yes, 0=no).
- Default
- 1
- Value
- 1
prefetch: append newly-available episodes to the player's queue -- Jellyfin/Emby/Plex only, experimental (1=yes, 0=no).
- Default
- 0
- Value
- 0
prefetch: skip episodes that haven't aired yet (1=yes, 0=no).
- Default
- 0
- Value
- 0
prefetch: retries when initially connecting to Sonarr/media server.
- Default
- 6
- Value
- 6
prefetch: Sonarr tag that excludes a series from prefetching.
DEBUG, INFO, WARNING, or ERROR.
- Default
- INFO
- Value
- INFO