Music Pipeline

Automated music acquisition, tagging, and streaming โ€” running on Proxmox CT 100 (docker-host). Last updated: April 13, 2026.

Pipeline Overview

Music flows through a fully automated chain: Lidarr searches for wanted albums via Headphones VIP indexer, sends grabs to NZBGet on the remote seedbox, rsync pulls completed downloads to Proxmox, Lidarr imports and organizes them, and Navidrome serves the final library for streaming.

Data flow:

Step Component Detail
1 Lidarr (Docker, CT 100) Searches Headphones VIP via MissingAlbumSearch (daily 4am cron). RSS sync runs every 15 min but grabs 0 โ€” Headphones VIP RSS feeds random new releases, not library-specific albums.
2 NZBGet (seedbox ismene.usbx.me) Downloads grabbed NZBs to ~/downloads/nzbget/completed/Music/ at ~70 MB/s average.
3 seedbox-sync.sh (cron, every 15 min) rsync pulls completed/Music/, completed/Books/, and complete/ โ†’ /nvmepool/ingest/ on Proxmox. Uses --remove-source-files to clean seedbox as files transfer. Partial resuming enabled.
4 LXC bind mount /nvmepool/ingest โ†’ /mnt/seedbox inside CT 100.
5 Docker bind mount /mnt/seedbox โ†’ /downloads inside Lidarr container.
6 Lidarr import Monitors /downloads/Music/ and imports matched albums to /music/, renaming per configured format. Requires โ‰ฅ80% MusicBrainz metadata match.
7 Navidrome (Docker, CT 100) Serves /mnt/music to audio clients (Feishin on desktop, Subsonic apps on mobile).
Lidarr Configuration
Setting Value
URL http://192.168.8.100:8686
Image lscr.io/linuxserver/lidarr:nightly
Version 3.1.2.4928 (nightly โ€” required for plugin support)
API key 3dc17d20ca664be4ac90fb89004f91b8
Config mount /opt/lidarr/data โ†’ /config
Downloads mount /mnt/seedbox โ†’ /downloads
Music mount /mnt/music โ†’ /music
Monitored artists 241
Missing albums ~10,000+ (93 artists added April 13)

Indexers:

Indexer Status Notes
Headphones VIP โœ… Working Primary source. Dedicated music Usenet indexer with proper t=music support.
NZBHydra2 โœ… Working Usenet indexer aggregator on seedbox. API key: BM7BCBP0RNBFIIRTJ32LGN9G4M. Base URL in Lidarr: http://192.168.8.221:15076/nzbhydra2. Note: altHUB (underlying indexer) lacks music-search caps so music-specific results are limited, but general searches work.

Download client: NZBGet at 192.168.8.221:16789 (SSH tunnel to seedbox port 13036).

Quality profiles: Any, Lossless (preferred), Standard. Set artists to Lossless for FLAC.

Release profile โ€” ignored terms (compilations and greatest hits are blocked to prevent import loop):

  • Greatest Hits, Best Of, The Essential, The Very Best
  • Collection, Definitive, Complete, Anthology, Ultimate
  • YouTube rip, SoundCloud rip, ytrip, camrip, Rock Mix, Rancho Texicano

Track naming format: {Album Title} ({Release Year})/{Artist Name} - {Album Title} - {track:00} - {Track Title}

Automation & Scheduling

Lidarr has no built-in scheduled MissingAlbumSearch โ€” this is a known design gap. The RSS sync (every 15 min) only grabs random new releases from the Headphones VIP feed, not library-specific missing albums. A Proxmox cron job compensates:

Cron job Schedule Purpose
seedbox-sync.sh Every 15 min Consolidated pull from seedbox โ€” both nzbget/completed/Music/ + Books/ and downloads/complete/ in one script
MissingAlbumSearch API call Daily 4:00 AM Actively searches all missing albums against all indexers โ€” the primary download trigger

Trigger MissingAlbumSearch manually:

curl -s -X POST 'http://192.168.8.100:8686/api/v1/command?apikey=3dc17d20ca664be4ac90fb89004f91b8' \
  -H 'Content-Type: application/json' -d '{"name":"MissingAlbumSearch"}'
Beets Post-Processor

Beets 2.7.1 is installed on CT 100 at /usr/local/bin/beet. Config at /root/.config/beets/config.yaml. Primary use is importing new music from the seedbox and handling compilations that Lidarr’s 80% threshold rejects.

Setting Value
Music directory /mnt/music
Library DB /root/.config/beets/library.db (~29MB)
Import mode move: yes, quiet: yes, quiet_fallback: asis
Match threshold 0.15 (distance) โ€” much looser than Lidarr’s 80%
Duplicate action skip
Compilations path Compilations/$album/$track $title

Plugins: musicbrainz, fetchart, embedart, lastgenre, scrub, chroma

Pipeline script: /usr/local/bin/beet-full-pipeline.sh โ€” DISABLED as of April 13, 2026. The initial bulk import is complete: 2,112 albums / 33,654 tracks / 1.4 TiB across 197 artists. The 30-minute cron was removed because the import had finished but was re-scanning 2,662 folders of duplicates/junk every 3 hours in an infinite loop. 134 potential hi-res/deluxe keepers were preserved in /mnt/seedbox/Music-Duplicates/ for manual review; 658 non-keepers and 1,870 junk-only folders were deleted.

Pipeline behavior:

  1. Checks for new files in /mnt/seedbox/Music
  2. If found, runs beet import -q /mnt/seedbox/Music to match, tag, and move to /mnt/music
  3. Cleans up empty directories left behind
  4. If no new files, exits immediately

Manual maintenance commands (run on CT 100 only when needed, not scheduled):

# Fetch missing cover art for albums without artwork
/usr/local/bin/beet fetchart

# Embed cover art into audio file metadata
/usr/local/bin/beet embedart

# Tag genres from Last.fm
/usr/local/bin/beet lastgenre

# Re-catalog any files in /mnt/music not yet in beets DB
/usr/local/bin/beet import -qA /mnt/music

Using beets for compilations (albums blocked by Lidarr’s release profile):

# SSH into CT 100 and run:
/usr/local/bin/beet import /downloads/Music/SomeAlbum/

Beets matches with 15% threshold, auto-fetches art, tags genre from Last.fm, moves to Compilations/ folder. Navidrome picks up automatically.

Docker Services
Service Image Port Purpose
Navidrome deluan/navidrome:latest 4533 Music streaming server (Subsonic-compatible). Scan schedule: 24h (filesystem watcher handles real-time). Config: env vars only, no toml. Volumes: /var/lib/navidrome:/data, /mnt/music:/music:ro
Lidarr lscr.io/linuxserver/lidarr:nightly 8686 Music collection manager and Usenet requester. Note: Lidarr has a known memory leak โ€” restart periodically if RAM usage exceeds 2GB (docker restart lidarr)
Planned Enhancements

Two Lidarr plugins are planned to supplement the Usenet pipeline. Both require the nightly branch (already active).

Plugin GitHub Purpose Status
Tidal (TrevTV) Lidarr.Plugin.Tidal Direct Tidal downloads โ€” FLAC lossless, Dolby Atmos, vast catalog. Best fix for compilations/greatest hits. Requires active Tidal subscription. Planned
Tubifarry (TypNull) Tubifarry YouTube fallback (128-256kbps AAC) + Soulseek via Slskd. Use as last resort only. Planned

Installing a plugin: System โ†’ Plugins in Lidarr UI โ†’ paste GitHub URL โ†’ Install โ†’ Restart.

Tidal auth flow (quirky): Add indexer โ†’ enter data path โ†’ Test (will error) โ†’ Cancel โ†’ refresh page โ†’ re-open Tidal indexer โ†’ copy the OAuth URL โ†’ log into Tidal in browser โ†’ copy the redirect URL โ†’ paste back into Lidarr. Redirect URLs are single-use.

Storage
Path (CT 100) Host ZFS dataset Purpose
/mnt/music nvmepool/music Tagged music library (Navidrome source) โ€” 33,654 tracks, 241 artists (197 from beets + 93 added to Lidarr April 13)
/mnt/seedbox nvmepool/ingest Seedbox landing zone (rsync target)
/mnt/seedbox/Music/ โ€” Empty โ€” beets import complete. New Lidarr grabs land here.
/mnt/seedbox/Music-Duplicates/ โ€” 134 potential hi-res/deluxe keepers pending review
/mnt/seedbox/Books/ โ€” Book library

Seedbox state (as of 2026-04-13):

  • completed/Music/: Active โ€” consolidated seedbox-sync.sh runs every 15 min, pulls from both nzbget and general complete paths
  • NZBGet: idle when queue is empty, average ~70 MB/s when downloading
  • Beets import complete โ€” /mnt/seedbox/Music/ is empty and ready for new Lidarr grabs
Troubleshooting
Symptom Cause Fix
Navidrome UI slow to display music Beets pipeline re-cataloging entire library every 30 min, causing constant Navidrome rescans Fixed April 2026: pipeline now only imports new seedbox files. Navidrome scan reduced to 24h (filesystem watcher handles real-time)
Lidarr using 4GB+ RAM Memory leak after extended uptime (13+ days observed) docker restart lidarr โ€” drops back to ~200MB
NZBGet idle, nothing downloading MissingAlbumSearch completed its run, queue empty Trigger manually (see Automation section) or wait for 4am cron
Queue full, NZBGet idle 60-item queue full of importFailed items blocking new grabs Blocklist + remove importFailed items via Activity โ†’ Queue
importFailed: album match not close enough Lidarr’s 80% MusicBrainz threshold not met For compilations: use beets. For others: blocklist and let Lidarr find different release
/downloads/Music/ empty in container Docker bind mount broken (Docker started before LXC mount) docker restart lidarr
RSS Sync: 0 grabbed Normal โ€” Headphones VIP RSS feeds random new music Expected behavior. Grabs only come from MissingAlbumSearch
importFailed: permissions error File ownership issue from NZBGet Check /downloads/Music/ permissions inside container
Stale lockfile blocking sync Previous rsync killed mid-run rm /tmp/sync-seedbox.lock on Proxmox