All apps · 0 apps
music-librarian
Docker app from MusicLibrarian's Repository
Overview
Readme
View on GitHubMusic Librarian
Self-hosted, taste-driven, resumable FLAC-preferred auto-fill for your Navidrome library. Runs as a Docker container on the Unraid box — no Claude Code / browser dependency. Seeds from what your household actually plays (Navidrome + Plex/Plexamp play counts, YouTube Music Takeout history), expands via Last.fm (taste-weighted + horizon), downloads through the existing Soulbeet API with a FLAC-preferred / high-quality-lossy fallback ladder, keeps favorited artists' full discographies current via MusicBrainz, and can re-acquire lossy albums as FLAC on a schedule. State is in SQLite, so restarts resume exactly where they left off.
Companion app, not a standalone downloader. It drives an existing Soulbeet instance and reads an existing Navidrome library — both must already be running. A free Last.fm API key is required; Tautulli (for Plex/Plexamp plays) is optional.
Install on Unraid (Community Applications)
Search Music Librarian in the Apps tab and install. The template pulls a
prebuilt image from ghcr.io/asherflynt/music-librarian — no building on the box.
On first start the container auto-seeds an empty /config with config.env,
secrets.env, exclude.txt and favorites.txt. Then:
- Edit
/mnt/user/appdata/music-librarian/secrets.envand fill inLASTFM_API_KEY,SOULBEET_USER,SOULBEET_PASS(your Navidrome/Soulbeet login). Optionally addTAUTULLI_API_KEY. The container waits for these — it never crash-loops — and picks them up within a minute of saving, no restart needed. - Set
SOULBEET_URLandNAVIDROME_URLin the template to your host's LAN IP and their ports (on bridge networking, notlocalhost). - Point the Music library / Free-space pool / Staging pool mounts at the right shares for your box.
Open the UI at http://<server>:8730. Every knob has hover help and is editable live.
Keep it on the LAN. The UI is unauthenticated by design and can change download targets and (with upgrades on) delete files. Do not put port 8730 behind a reverse proxy or tunnel. See the security note under Web UI below.
Web UI
http://<server>:8730 — progress, real library quality breakdown, download stats, favorites, new releases, the taste ranking, and every tunable setting.
LAN only, no auth, by design — same posture as slskd/Soulbeet/Navidrome on this network. Do not route it through the Cloudflared tunnel: it can change download targets and, with upgrades enabled, cause files to be deleted.
State-changing requests (all POSTs) are CSRF-guarded: a request carrying a cross-origin
Originheader is rejected, so a random web page you happen to open can't silently drive the API (this also blunts DNS-rebinding). Requests with noOrigin— curl, scripts — are still allowed, so automation is unaffected. This is hardening, not a substitute for auth: anyone who can reach port 8730 can still use the UI directly, which is why it must stay on a trusted LAN.
Layout on the server
/mnt/user/appdata/librarian/
secrets.env # LASTFM_API_KEY, SOULBEET_USER/PASS, TAUTULLI_API_KEY (you fill in)
config.env # live-tunable settings (edit in the UI or here)
exclude.txt # kids-music artist blocklist (edit in the UI or here)
favorites.txt # full-discography artists (edit in the UI or here)
takeout/ # drop Google Takeout YT Music history JSON here
state/state.db # SQLite progress (auto)
state/status.json# live status snapshot (auto)
upgrade-swap.log # every verified swap + deletion (auto)
/mnt/user/Media/Music/_upgrades/ # FLAC upgrade staging, pre-verification (auto)
Build & run from source (advanced)
Not needed for a Community Applications install — that pulls the prebuilt image. This is for running from a local clone (the
update.shworkflow).
docker build -t librarian /mnt/user/appdata/librarian/build
docker run -d --name librarian --restart unless-stopped \
-e SOULBEET_URL=http://<unraid-ip>:9765 \
-e NAVIDROME_URL=http://<unraid-ip>:4533 \
-e MUSIC_PATH=/music -e FREE_SPACE_PATH=/music -e TARGET_FOLDER=/music \
-v /mnt/user/appdata/librarian:/config \
-v /mnt/user/appdata/librarian/state:/data \
-v /mnt/user/Media/Music:/music:ro \
librarian
MUSIC_PATH is mounted read-only just for size/track measurement; downloads land in
the library via Soulbeet/beets (which has its own writable mount).
Adjusting
Every setting is editable in the UI — hover any field for a plain-English
explanation of what it does and what happens if you change it — or by editing
config.env directly. The UI writes that same file and preserves its comments.
Changes take effect on the next loop; no restart, no rebuild.
The common ones:
- Want more music? Raise
TARGET_TB. It resumes immediately from where it stopped. - Getting music you don't recognise? Lower
EXPLORE_RATIO. - Stop temporarily: the Pause button (or
PAUSED=1). Nothing is lost. - Wrong taste:
TASTE_HALF_LIFE_DAYScontrols how much old listening still counts. - Kids' music: add artists in the UI's Excluded panel, or to
exclude.txt. - Want everything by an artist: star them in Navidrome, click ★ in the UI, or add
them to
favorites.txt.
Settings reference
Every knob, what it does, and its default. This section is generated from the same
text the UI shows on hover (HELP in web.py) via tools/gen_settings_doc.py —
so the docs and the UI cannot drift apart. Edit HELP, then run:
python3 tools/gen_settings_doc.py # rewrite this section
python3 tools/gen_settings_doc.py --check # fail if out of date
Targets & pacing
TARGET_TB
Stop once the library reaches this size · default 3 · 0.0 – 500.0
The size you want your music library to grow to, in terabytes. The librarian keeps downloading until the library hits this OR the track count target, whichever comes first, then idles.
Raise it and it picks straight back up where it left off — nothing is lost or re-downloaded. Lower it below your current size and it stops cleanly; it never deletes anything to get back under the number.
This is the one to change when you clear space and want more music.
TARGET_TRACKS
…or once it reaches this many tracks · default 100000 · 0 – 100000000
The other finish line: stop once the library holds this many tracks. Whichever target is hit first wins.
In practice size is almost always the binding limit — 100,000 FLAC tracks would be far more than 3 TB — so treat this as a safety ceiling rather than the real goal.
EXPLORE_RATIO
0 = only what you love · 1 = only new horizons · default 0.30 · 0.0 – 1.0
How adventurous the recommendations are.
At 0 the librarian only fetches more of what you already play and artists that sound like them. At 1 it only chases artists you don't own from genres you lean into. The default 0.3 spends about 70% of its effort deepening your existing taste and 30% stretching it.
Turn it down if you're getting music you don't recognise; turn it up if the library feels like an echo chamber.
MIN_FREE_GB
Hard floor — never fill the pool below this · default 500 · 0.0 – 100000.0
A safety net for your storage pool. If free space on the cluster pool drops below this many gigabytes, the librarian stops adding music entirely, no matter what the targets say.
This exists so a runaway fill can't fill the pool that also holds your movies, TV, and everything else. Don't set it near zero — a full ZFS pool performs badly and is unpleasant to dig out of.
STAGING_MIN_FREE_GB
Pause if the NVMe staging pool gets this low · default 80 · 0.0 – 100000.0
Downloads land on the fast NVMe cache first, then beets imports them into the library. If that cache drops below this many gigabytes free, the librarian pauses new downloads for a couple of minutes to let imports drain it.
It protects the cache SSD from filling up mid-transfer, which would stall every download at once.
CONCURRENCY
How many albums to download at once · default 3 · 1 – 16
How many albums the librarian works on simultaneously.
Higher isn't better: Soulseek peers are ordinary people's computers, and hammering several at once gets you queued, throttled, or banned. 3–4 is the sweet spot. Raise it only if downloads are clearly idling.
TASTE_REFRESH_MIN
How often to re-read your play counts (minutes) · default 360 · 5 – 100000
How often the librarian re-reads what you've been playing from Navidrome, Plex/Plexamp, and your YouTube Music history, and re-ranks artists.
The default of 360 (6 hours) is plenty — your taste doesn't change by the minute, and each refresh costs a round of API calls. Use the 'Refresh taste' button if you want it to happen right now.
MEASURE_EVERY_SEC
How often to re-scan the library (seconds) · default 300 · 30 – 86400
How often the librarian walks the library to recount size, tracks, and audio quality.
The scan is incremental — files that haven't changed are not re-read — so this is cheap. Lower it if you want the progress numbers to feel more live; raise it if the disk is busy.
SCAN_MAX_PROBES_PER_PASS
How many new files to analyse per scan (safety limit) · default 250 · 10 – 100000
How many new or changed files the librarian opens per scan pass to read their real audio format.
This is a safety limit rather than a speed dial. Your library is reached through Unraid's /mnt/user layer, which is a single shared chokepoint that Plex, slskd, beets and everything else also go through. Counting files there is cheap; opening thousands of them in a tight loop is not — that is what locked the server up hard enough to need a power cycle on 17 Jul 2026.
Files that don't fit in a pass simply wait for the next one, so the scan still finishes — it just spreads the load. At the default it works through roughly 3,000 files an hour. Only raise it if you know the server is idle.
PAUSED
Stop queueing downloads, keep everything else running · default off · on / off
Pauses new downloads without stopping the container or losing any progress.
In-flight transfers finish, imports keep happening, and the UI stays live. Flip it back off and it resumes exactly where it was. Same as the Pause button up top.
Taste weighting
TASTE_HALF_LIFE_DAYS
A play this old counts half as much · default 365 · 1.0 – 36500.0
Makes recent listening matter more than old listening.
At the default 365, a song you played a year ago counts half as much as one you played today; two years ago, a quarter. Without this, a 2019 obsession would weigh exactly as much as last week and the library would grow toward who you used to be.
Lower it (e.g. 180) to chase your current mood harder. Raise it (e.g. 1095) to give long-time favourites more say.
WEIGHT_NAVIDROME
How much Navidrome plays count · default 3.0 · 0.0 – 100.0
How much weight to give plays from Navidrome — this library, in the web player or a Subsonic app.
This is direct evidence of what you like, so it's weighted high by default. Note Navidrome only reports an album's LAST played date, so the recency decay here is coarser than for Plex.
WEIGHT_PLEX
How much Plex / Plexamp plays count · default 3.0 · 0.0 – 100.0
How much weight to give plays from Plex and Plexamp, read via Tautulli.
Plexamp is a Plex client, so its plays are recorded by Plex and never reach Navidrome — without Tautulli they'd be invisible. Requires TAUTULLI_API_KEY in secrets.env; without it this signal is simply skipped.
There's no double-counting: a play is recorded by whichever server actually served the audio, never both.
WEIGHT_YTMUSIC
How much YouTube Music history counts · default 1.0 · 0.0 – 100.0
How much weight to give your YouTube Music listening history from Google Takeout.
Weighted lower than Navidrome/Plex by default because it's noisier — it includes a lot of incidental, background, and one-off listening rather than music you deliberately chose. It's most valuable as the cold-start signal before you've played much in this library.
Favorites (full discography + new releases)
FAVORITES_ENABLED
Fetch full discographies for favourited artists · default on · on / off
Turns the favourites system on or off.
When on, any artist you favourite gets their ENTIRE discography downloaded, and is re-checked forever so new releases arrive automatically. Favourite an artist by starring them in Navidrome, clicking ★ in the Taste list, or adding them to favorites.txt.
Turning this off leaves existing downloads alone; it just stops new discography syncing.
FAVORITE_SYNC_HOURS
How often to check favourites for new releases · default 24 · 1 – 8760
How often to ask MusicBrainz whether your favourited artists have released anything new.
This is what makes new albums show up on their own. Daily (24) is plenty — artists don't release albums hourly, and MusicBrainz allows only one request per second. Use 'Sync favorites' to check right now.
FAVORITE_PRIORITY
Queue position vs ordinary discovery (higher = sooner) · default 100 · 0 – 10000
How far ahead of the normal discovery queue favourites jump.
This matters more than it sounds: the 100k-track fill generates thousands of candidates, so without a priority boost a favourite's discography would sit behind all of them and effectively never download. Anything above 0 puts favourites first; the exact number only matters if you want tiers.
FAVORITE_INCLUDE_EP
Include EPs in a favourite's discography · default on · on / off
Whether EPs count as part of 'the discography'.
On by default — EPs are usually real, wanted releases. For Glass Animals this is the difference between 4 albums and 7 releases.
FAVORITE_INCLUDE_SINGLES
Include singles — warning, there are a LOT · default off · on / off
Whether to also download every single.
Off for a good reason. Glass Animals alone has 29 singles and 26 remix singles against just 4 studio albums — turning this on takes them from 7 releases to 36, and almost all of it is duplicate versions of tracks you already have from the albums.
Only turn this on for an artist whose singles genuinely aren't on any album.
FAVORITE_INCLUDE_LIVE
Include live albums and broadcasts · default off · on / off
Whether live recordings count as part of the discography.
Off by default. These are often radio sessions and broadcast recordings of songs you already own, and their audio quality is inconsistent.
FAVORITE_INCLUDE_COMPILATIONS
Include compilations and greatest-hits · default off · on / off
Whether compilations, best-ofs, and greatest-hits count.
Off by default, because if you already have the studio albums a compilation is almost entirely duplicate tracks.
FAVORITE_INCLUDE_REMIX
Include remix albums and remix singles · default off · on / off
Whether remix releases count.
Off by default. Remixes are the single biggest source of near-duplicates — for Glass Animals there are 26 remix singles alone.
Lossy → FLAC upgrades
UPGRADE_ENABLED
Re-download lossy albums as FLAC when one appears · default off · on / off
Periodically re-checks albums you own as MP3 or AAC to see whether a FLAC version has shown up on Soulseek since you got them.
Off by default. When a FLAC is found it's downloaded to a staging area, NOT straight into your library. A separate script then verifies it — every file must be FLAC, the track count can't drop, every file must fully decode, and the running time must match within 5% — before it replaces the old copy.
Your old lossy copy is DELETED once the replacement is verified and confirmed in place. If any check fails, nothing is touched.
UPGRADE_HOUR
Hour of day to run the upgrade check (0–23) · default 3 · 0 – 23
What time of day the nightly upgrade pass runs, in 24-hour server local time (3 = 3am).
It runs once a day at this hour. Pick a time when nobody's streaming and the server is otherwise quiet.
UPGRADE_MAX_PER_RUN
Albums checked per nightly pass · default 10 · 1 – 1000
The most albums the upgrade pass will check in one night.
This is the main 'don't overwhelm anything' dial. Each check is a full Soulseek search against real peers, so checking hundreds at once is both slow and a good way to get banned. At 10/night it works through a backlog steadily without anyone noticing.
UPGRADE_RECHECK_DAYS
Don't re-check the same album within this many days · default 30 · 1 – 3650
How long to wait before asking about an album again after finding no FLAC.
If nobody on Soulseek had a FLAC of an album yesterday, they almost certainly won't today either. Waiting 30 days stops the pass from burning its whole nightly budget re-asking the same hopeless albums instead of trying new ones.
UPGRADE_ONLY_WHEN_IDLE
Wait for the main download queue to go quiet first · default on · on / off
Makes upgrades yield to the main fill.
On by default. Upgrades and normal downloads compete for the same Soulseek peers and the same bandwidth; upgrades are a nice-to-have, so they wait rather than slow down music you don't have yet.
Play tracking
Three signals, each recency-weighted by exponential decay (TASTE_HALF_LIFE_DAYS,
default 365 — a play a year old counts half as much as one today), then combined by
the WEIGHT_* knobs:
| Source | How | Decay granularity |
|---|---|---|
| Navidrome | Subsonic getAlbumList2?type=frequent |
per album — Subsonic exposes no per-play timestamps, only playCount + last-played |
| Plex / Plexamp | Tautulli get_history |
per play (each row has a unix timestamp) |
| YouTube Music | Takeout watch-history.json |
per listen (each entry has an ISO-8601 time) |
Plexamp needs Tautulli. Plexamp is a Plex client, so its plays are recorded by
Plex Media Server and never reach Navidrome — polling Navidrome alone misses them
entirely. Set TAUTULLI_API_KEY in secrets.env to count them. It's optional: absent,
the Plex signal is simply skipped, never an error.
There is no double-counting between Navidrome and Plex: a play is recorded by whichever server actually served the audio, never both.
Favorites — full discography + new releases (MusicBrainz)
A favorited artist gets their entire discography queued (at FAVORITE_PRIORITY, so
ahead of the exploration crawl) and is re-checked every FAVORITE_SYNC_HOURS forever,
so new releases are picked up automatically.
Why MusicBrainz and not Last.fm. They answer different questions, and each is useless at the other's:
- Last.fm → discovery.
getSimilar/tag.getTopAlbumsanswer "who else might I like". MusicBrainz has no similarity data at all, so Last.fm is not replaceable here and remains the recommendation engine. - MusicBrainz → discography. Canonical release-groups with release dates and
release types. Last.fm's
getTopAlbumsreturns neither, so it cannot detect a new release or exclude a live bootleg — it is structurally unable to do this job.
Release-type filtering matters more than it sounds. Glass Animals has 75 release-groups; only 7 are real albums/EPs:
FAVORITE_INCLUDE_EP=1 -> 4 albums + 3 EPs = 7 (default)
FAVORITE_INCLUDE_SINGLES=1 -> +29 singles = 36
FAVORITE_INCLUDE_REMIX=1 -> +26 remix singles
FAVORITE_INCLUDE_LIVE=1 -> +5 live broadcasts
FAVORITE_INCLUDE_COMPILATIONS=1 -> +3 compilations
MusicBrainz enforces 1 request/sec, and throttling returns 200 with an empty
body rather than an error — so the client rate-limits at 1.1 s and treats a missing
expected key as a retryable failure, never as "this artist has no releases" (which
would permanently mark a discography complete).
exclude.txt wins over favorites.txt. Both are deliberate acts, but the blocklist
is the safety-oriented one. An artist in both is skipped and the conflict is logged.
Scheduled lossy → FLAC upgrades
Off by default (UPGRADE_ENABLED=0). When on, one bounded pass runs daily at
UPGRADE_HOUR: it takes up to UPGRADE_MAX_PER_RUN albums that mutagen classified
as lossy, searches Soulseek, and stages a FLAC only if a true FLAC exists
(never a lossy→lossy sidegrade). UPGRADE_ONLY_WHEN_IDLE=1 keeps it from competing
with the main fill for Soulseek slots, and UPGRADE_RECHECK_DAYS stops it re-asking
about the same album.
Staging goes to <music>/_upgrades — inside Soulbeet's existing /music mount.
That's not arbitrary: /api/downloads/queue does create_dir_all(target_folder)
inside the Soulbeet container, so a path outside its mounts (a bare /upgrades)
would be created in its writable layer — invisible to the host and discarded on
recreate, with no error. The staging dir is excluded from the library scan and carries
a .ndignore so Navidrome doesn't index half-verified albums.
The swap, and why it deletes
upgrade-swap.sh (User Script, every 30 min) verifies each staged album against four
gates, and touches nothing unless all pass:
- every audio file is
.flac - FLAC track count ≥ the existing album's
- every file decodes cleanly (
ffmpeg -v error -i … -f null -) — catches the truncated/corrupt transfers Soulseek routinely produces - total duration within 5% of the existing album — catches wrong-edition rips
Only then does it beet remove --delete the old album and beet move the FLAC in,
and only after confirming the replacement landed does it drop the staged copy.
Configured to delete the old lossy copy; set ARCHIVE_DIR in the script to move
it aside instead. Every swap and deletion is logged to upgrade-swap.log.
Gate 3 is the one that matters: without a real decode check, a truncated FLAC passes a header check happily, and you'd trade a good MP3 for an unplayable file.
flac -t isn't used because no flac binary exists on the host or in the soulbeet
container — and the soulbeet image has no shell at all, so everything is exec'd as
a direct binary (ffmpeg, ffprobe, beet) with file enumeration done host-side.
Quality ladder (FLAC preferred, never required)
For each album/track, best available wins:
| Tier | Format | Notes |
|---|---|---|
| 1 | FLAC | lossless |
| 2 | ALAC (.m4a ≥ ALAC_MIN_KBPS, default 500) |
also lossless — ranked above any lossy source, even a higher-scoring one |
| 3 | High-quality lossy (mp3/aac/.m4a-as-AAC) at quality_score ≥ 0.55 (~320 kbps / V0) |
320 and V0 preferred |
| — | skipped | low_quality_only (only sub-threshold lossy) or no_source |
The .m4a trap: .m4a is a container used by both ALAC (lossless) and AAC
(lossy), and the backend only reports the file extension, not the codec — so
"prefer m4a" would silently pull lossy AAC most of the time. Bitrate is the real
discriminator: ALAC runs ~600–900 kbps, AAC caps ~320. The librarian computes
effective bitrate from size/duration and only calls an .m4a lossless if it
clears ALAC_MIN_KBPS. Tune via the ALAC_MIN_KBPS env var.
For files already on disk the guess isn't needed: mutagen reports the real codec
(alac vs mp4a.40.2), which is what the library quality stats and the upgrade
scanner use. Verified against this library — all 16 .m4a files are AAC at 256–320
kbps, correctly classified as lossy rather than mistaken for lossless ALAC.
Every fallback is documented. When no FLAC exists, the log records what it landed on and why:
FALLBACK [Artist - Album]: no FLAC source -> ALAC (.m4a @ ~874 kbps, lossless)
FALLBACK [Artist - Album]: no lossless source -> mp3 @ ~336 kbps (lossy)
SKIPPED [Artist - Album]: only sub-threshold lossy sources
and status.json carries per-item detail plus a running lossless ratio:
"queued_flac": 412, "queued_alac": 9, "queued_lossy": 63,
"lossless_total": 421, "lossless_pct": 87.0,
"recent_fallbacks": [
{"artist": "...", "album": "...", "format": "mp3", "kbps": 336, "lossless": false}
]
The SQLite candidates table keeps fmt + kbps for every acquisition, so you can
always audit exactly what is lossless vs. fallback.
Status
cat /mnt/user/appdata/librarian/state/status.json or docker logs librarian — shows
library TB, track count, % to target, free space, and FLAC-vs-lossy counts.
The rescue sweep (deliberately NOT in this container)
Soulbeet's DownloadMonitor doesn't reliably trigger a beets import for every
completed download under sustained concurrent load — fully-downloaded albums can
sit in slskd's staging dir with no import ever attempted. A periodic sweep re-runs
beet import against that staging dir to catch them.
That sweep intentionally lives outside this container, as an Unraid User Script
(librarian-rescue-sweep, every 20 min) that calls
docker exec soulbeet beet import ....
Why not run beets in this container? Because it would mean a second beets install
writing the same .beets_library.db as Soulbeet's. Pinning versions to match only
papers over that — if Soulbeet's image ever bumps beets, two different versions would
share one library db, which beets does not support. Calling Soulbeet's own beets via
docker exec uses the canonical version and config, with zero drift.
Why not have this container docker exec? That needs /var/run/docker.sock mounted
in, granting root-equivalent host control to a container that parses external data
(Takeout JSON) and talks to third-party APIs. Not worth it for a convenience feature.
The host-side User Script avoids both problems, and runs on its own schedule independent of this container's auth/paused state.
Maintainer: releasing & Community Applications
The image is published to GHCR by
.github/workflows/docker-publish.yml on every
push to main and every v* tag (multi-arch amd64/arm64). Cut a release with:
git tag v2.1.0 && git push origin v2.1.0
Then make the package public once: GitHub → your profile → Packages →
music-librarian → Package settings → Change visibility → Public. CA can
only pull a public image.
Community Applications reads two files from the repo root/templates/:
ca_profile.xml— repository metadata + icon.templates/music-librarian.xml— the app template (<TemplateURL>must stay pointed at that file's raw URL).
To submit or update the listing, go to https://ca.unraid.net/submit, point it at this repository, and run Validate then Scan. Re-run after any XML change.
Install music-librarian on Unraid in a few clicks.
Find music-librarian 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.
Requirements
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/asherflynt/music-librarian:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8730]- Network
bridge- Shell
sh- Privileged
- false
Template configuration
Web UI / API port. LAN only — do not expose it through a reverse proxy or tunnel.
- Target
- 8730
- Default
- 8730
- Value
- 8730
Settings, secrets and Google Takeout drop-folder. Auto-seeded on first run; your edits are preserved across updates.
- Target
- /config
- Default
- /mnt/user/appdata/music-librarian
- Value
- /mnt/user/appdata/music-librarian
SQLite progress database and live status snapshot. Keep this to resume exactly where you left off.
- Target
- /data
- Default
- /mnt/user/appdata/music-librarian/state
- Value
- /mnt/user/appdata/music-librarian/state
Your existing music library, mounted read-only for size / track-count / quality measurement only. Downloads land via Soulbeet, not through this mount.
- Target
- /music
- Default
- /mnt/user/Media/Music
- Value
- /mnt/user/Media/Music
The pool that holds the library. Its free space is measured against MIN_FREE_GB — the librarian stops adding music if this pool drops below that floor. Point it at your bulk pool (e.g. /mnt/cluster) or /mnt/user.
- Target
- /cluster
- Default
- /mnt/user
- Value
- /mnt/user
The fast pool Soulbeet downloads land on before beets imports them. Measured against STAGING_MIN_FREE_GB to protect the cache SSD. Point it at the same pool Soulbeet/slskd stage into.
- Target
- /cache
- Default
- /mnt/cache
- Value
- /mnt/cache
Where Soulbeet's API is reachable from inside this container. On bridge networking use the Unraid host's LAN IP and Soulbeet's host port, NOT localhost or a container name.
- Default
- http://192.168.1.10:9765
- Value
- http://192.168.1.10:9765
Where your Navidrome server is reachable from inside this container. On bridge networking use the host's LAN IP, not localhost.
- Default
- http://192.168.1.10:4533
- Value
- http://192.168.1.10:4533
OPTIONAL. Tautulli base URL, to count Plex/Plexamp plays toward your taste. Leave blank to skip the Plex signal (never an error). The API key itself goes in /config/secrets.env.
Advanced. The library path as SOULBEET sees it (passed to Soulbeet's download queue), not as this container sees it. Only change it if Soulbeet mounts your library somewhere other than /music.
- Default
- /music
- Value
- /music