Navidrome (music)
Navidrome scans library/music, keeps the music database and serves the
songs. SoundStorm talks to it over the Subsonic API (with OpenSubsonic extensions) and builds albums,
radio, lyrics and beat analysis on top.
Why Navidrome
Jellyfin could serve music too, but its music support is a second-class citizen next to its video support, structurally. Navidrome gets multi-value artist tags, album artist versus artist, compilations, ReplayGain, smart playlists and a fast scanner right - exactly the music engine a fork of a media server would have meant rebuilding by hand. Its image is about 348 MB against Jellyfin's 2.5 GB.
Provisioning
Navidrome's first-run admin form posts to /auth/createAdmin, and that endpoint works
only while no user exists - so driving it is safe: it can never take over a configured server.
SoundStorm generates the password, creates the admin, and keeps the credentials in its state. The
music folder is mounted read-only. Compose sets a few environment variables, and their names matter:
| Setting | Why |
|---|---|
ND_SCANINTERVAL: 1m | Not ND_SCANSCHEDULE. Navidrome ignores unknown keys silently, so the wrong name looked like it worked while no periodic scan ever ran. Check --help in the container before trusting any of these names. |
ND_SUBSONIC_DEFAULTREPORTREALPATH | Report real file paths rather than ones built from tags (below). |
ND_ENABLETRANSCODINGCONFIG | Lets SoundStorm add its own listening transcoding for beat analysis; without it the API answers 405. |
ND_ENABLEEXTERNALSERVICES: false | Nothing leaves the house from Navidrome itself. |
The household shares this one account. Favorites, playlists and history are kept by SoundStorm per
person, because anything stored in Navidrome would be everybody's at once. A second, non-admin account,
audiomuse, is made through Navidrome's native /api/user for
AudioMuse-AI.
The calls SoundStorm makes
Every request carries Subsonic token authentication: a fresh salt and the MD5 of password plus
salt, in the query string. That is the protocol - and why transport errors are passed through
httpx.Redact before anyone sees them, since the URL carries a credential.
| Call | Used for |
|---|---|
search3 | Search, and browsing the whole song shelf (an empty query returns everything) |
stream | Songs, with maxBitRate and format=mp3 for data saver, and the listening transcoding for beats |
getCoverArt | Covers, resized by Navidrome to the size asked |
getSong | One song by id, and its real path for deletion |
getAlbum, getArtist | Resolving old tag-based album and artist ids |
getRandomSongs, getGenres | Library mixes |
getLyricsBySongId | Local lyrics, synced from a .lrc beside a song |
startScan | "Look now" after an upload - the quick kind, cheap enough to fire per drop |
Verified quirks
- Its own sort is not the merge's order.
search3lists songs in an order of its own; of the first 50 by title in a 4,413-song library, its first 50 held none. Scrolling 40 pages through the merge gave 240 distinct songs and 1,760 repeats. So the adapter fetches the whole shelf, orders it withmedia.Lessand cuts, cached for 30 seconds - after which the same 40 pages went from 28.6 s to 3.2 s with no repeats. - Paths were made up. Unless told otherwise, Navidrome reports a path built from the
tags -
Artist/Album/01-06 - Title.m4afor a file really called06 Title.m4a- which looks real exactly when tags and folders agree. Deleting a song used that path. With the real-path setting on, paths are absolute in Navidrome's container and made relative to the music root; a path that is not real makes deletion refuse rather than guess. - The real-path setting is read once per client, when Navidrome first meets it. Its
record for the old client name kept sending made-up paths after the setting was on, so SoundStorm now
introduces itself as
soundstorm-app, which every install meets fresh. - ReplayGain comes through as OpenSubsonic
replayGain(checked on 0.64.1), which the player levels with. - Lossy will not become lossless. Asked for a lossy song as "flac", Navidrome sends
Opus. SoundStorm therefore registers a transcoding under its own name,
sslisten(subsonic/listen.go,PrepareListening), which converts to mono FLAC as asked, for the server's own beat analysis. A refusal is remembered for ten minutes, and phones then hear songs themselves. Navidrome caches each conversion (about 2.6 MB for four minutes) in its 100 MB cache.
Albums from folders
Navidrome groups albums by tags, which on a real library made 1,467 albums out of 551 album folders.
The adapter's folders.go regroups Navidrome's own song list by path - artist folder, album
folder, discs inside - with ids f: plus the folder path. See
Music.
Deleted files
Navidrome is the one backend that needed no help: a deleted file's row is flagged missing
and dropped from search3 by Navidrome itself. Its database can hold dozens of tracks for an
empty folder while answering search with none of them, which is exactly right.
Version
The image follows latest; behaviours above were checked against 0.64.0 and 0.64.1.
Re-verify the environment names and the transcoding API if the version moves.