Navidrome: The Self-Hosted Music Server That Streams What You Already Own
"Spotify knows what you listened to at 3 a.m. last Tuesday. Navidrome doesn't know anything — because there's no one to tell."
A decade of streaming subscriptions has produced a strange outcome: people pay monthly for access to music they don't own, and their listening history has become a data asset someone else holds. Navidrome (GitHub: navidrome/navidrome) is the open-source answer for anyone who still has actual music files. As of September 2026 it carries roughly 23,000 stars, is licensed GPL-3.0, ships as v0.62.0, and is written in Go as a single self-contained binary with a React UI embedded inside it. Point it at a folder of music and you get a Spotify-like web player plus compatibility with dozens of mobile apps — running on your hardware, on your network.
This is the honest breakdown: how it works, the Subsonic API ecosystem that makes mobile actually usable, a real deployment walkthrough, what it costs, and the limitation that trips up everyone who tries it: Navidrome provides no music whatsoever.
1. The Catch, Stated Up Front
Let's deal with this before anything else, because it's the #1 source of disappointment.
Navidrome is a server for music you already have. It does not include a catalogue. It does not discover new artists. It has no radio, no algorithmic recommendations, no "Discover Weekly." If your music collection is forty MP3s from 2009, your Navidrome experience will be forty MP3s from 2009.
This isn't a flaw — it's the entire design. Navidrome replaces the delivery mechanism of streaming, not the catalogue. You're building a personal streaming service, and a personal streaming service is only as good as your personal library.
So the honest question to ask before installing: do you own music files? If yes — FLACs you ripped, downloads you bought, a collection inherited from someone with excellent taste — Navidrome is close to magic. If no, it's an empty player, and no amount of configuration changes that.
2. How It Works
The architecture is refreshingly simple:
1. Point Navidrome at a music folder. It scans the files, reads embedded metadata (via a forked TagLib binding), extracts artwork, and builds an index in SQLite.
2. Browse and play through the built-in web UI — albums, artists, genres, playlists, search, favourites, play counts.
3. Or play through any Subsonic-compatible mobile app, which is where the real magic happens.
That last point deserves emphasis. Navidrome implements the Subsonic API (and its modern successor, OpenSubsonic), an open protocol that originated with the Subsonic music server and has become the de facto standard for self-hosted music. The practical consequence: you are not locked into Navidrome's own client. Dozens of apps on iOS and Android speak the protocol, so you can pick the one whose interface you actually like — including excellent options like Symfonium, DSub, and Finamp on Android, and play:Sub, Amperfy, or Elyric on iOS.
This is an unusually healthy position for a self-hosted project. Most self-hosted tools give you one mediocre client and a shrug. Navidrome gives you a protocol and an ecosystem.
On the technical side: single Go binary, React UI compiled in, SQLite for the index, FFmpeg shelled out for transcoding, and a WebAssembly plugin system. It runs comfortably on a Raspberry Pi and has been tested with libraries around 900,000 tracks.
3. Transcoding: Why This Matters on Mobile
You have a FLAC collection. FLAC is large. Streaming FLAC over mobile data will destroy your data plan in an afternoon.
Navidrome transcodes on the fly. Configure a bitrate per user or per client, and when a mobile client requests a track, Navidrome converts it — FLAC to Opus or MP3 — in real time. You hear essentially the same music at a fraction of the bandwidth.
This is the feature that makes a self-hosted music server actually practical outside your home network. Set 320 kbps for LAN and 128 kbps Opus for cellular, and a long commute costs a few hundred megabytes rather than several gigabytes.
The requirement: FFmpeg must be available on the host (or in the container). The official Docker image includes it; bare-metal installs need it installed separately.
4. Deployment Walkthrough
Docker is the cleanest path:
services:
navidrome:
image: deluan/navidrome:0.62.0
container_name: navidrome
user: 1000:1000 # must match the owner of your music files
ports:
- "4533:4533"
restart: unless-stopped
environment:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: ""
ND_ENABLETRANSCODINGCONFIG: "true"
ND_TRANSCODINGCACHESIZE: 200MB
ND_ENABLEGRAVATAR: "false"
ND_ENABLEEXTERNALSERVICES: "false"
ND_LASTFM_ENABLED: "false"
ND_SPOTIFY_ENABLED: "false"
ND_ENABLEINSIGHTSCOLLECTOR: "false"
volumes:
- ./data:/data
- /path/to/your/music:/music:ro
The details that matter:
user: 1000:1000must match the UID/GID owning your music files, or Navidrome won't be able to read them. This is the most common first-run failure.- Mount music
:ro(read-only). Navidrome never needs to write to your music, and read-only mounting guarantees it can't. ND_ENABLEEXTERNALSERVICES: "false"and the Last.fm/Spotify flags — these disable integrations that call out to third parties. More on this in the privacy section.ND_ENABLEINSIGHTSCOLLECTOR: "false"— turns off anonymous usage collection.ND_BASEURL— set this if you're serving under a subpath like/music. Getting it wrong produces a UI that loads but can't find its assets.
For remote access, use a VPN (Tailscale or Headscale) rather than port-forwarding. Music servers are exactly the kind of thing you don't want broadly reachable.
5. Multi-User and Multi-Library
Navidrome supports multiple users, each with their own play counts, favourites, playlists, and permissions. For a household, this is the difference between "my server" and "our server" — nobody's play count pollutes anybody else's, and you don't inherit your partner's questionable playlist on your home screen.
Multi-library support lets you expose different folders to different users: your music library for everyone, an audiobook folder for specific accounts, a kids' music folder for the kids. Permissions are per-library.
This is genuinely well-executed and is one of the reasons Navidrome overtook earlier self-hosted music servers in popularity.
6. The Honest Limitations
It provides no music. Stated first and repeated because it's the dealbreaker. You need files.
No video. Audio only. If you want films and TV too, that's Jellyfin — a different tool with different resource requirements.
No official mobile client. You depend on third-party Subsonic apps. The ecosystem is good, but "good third-party options" is not the same as "official, guaranteed-maintained client." Some are paid, some are abandoned periodically, and features vary between them.
External service integrations leak data by default. Navidrome can pull artist metadata and artwork from Last.fm, Spotify, Deezer, and ListenBrainz. That means outbound requests revealing what's in your library. Disable them if you self-host for privacy.
SQLite is the only database option (MySQL support exists in some configurations, but SQLite is the standard path). Fine for personal libraries; a consideration for very large concurrent deployments.
No discovery or recommendation features. No radio, no algorithmic playlists, no "because you listened to..." If you rely on Spotify's discovery, you'll feel the absence and need to replace it with something else.
Metadata quality depends on your tags. Garbage tags produce a garbage library. Navidrome reads what's in the files; it does not magically fix fifteen years of inconsistent tagging. Budget time with a tagger like MusicBrainz Picard.
No formal support or SLA. Community-driven project. If it breaks, you fix it or you wait.
7. What It Costs
| Item | Cost |
|---|---|
| Navidrome license | $0 (GPL-3.0, no paid tier, no feature gating) |
| Hardware you already own | $0 |
| Raspberry Pi (if you need one) | ~$50–80 one-time |
| VPS (optional, for remote access without a VPN) | ~$5–15/month |
| Storage | Your existing disks |
| Total | $0 marginal |
There is no paid tier. Navidrome has no commercial version, no pro features, no seat limits — everything is in the free GPL-3.0 build.
Compare with Spotify Premium at roughly $12/month: that's $144/year, forever, for access rather than ownership. Over ten years, that's $1,440 and you still own nothing. The honest counterweight is that Spotify gives you a catalogue of tens of millions of tracks for that money, which Navidrome categorically cannot.
The realistic answer for many people is both: Navidrome for the music you own and love, a streaming service for discovery — then buy or download what you actually want to keep. That's not a compromise; it's how listening worked before subscriptions, and it's cheaper.
8. Where Your Data Lives
This is where a music server is more interesting than it sounds.
Think about what a listening history reveals. Not just taste — schedule. What you play at 2 a.m. versus 8 a.m., what you play when you're working out, the album you looped for three days after a breakup, the children's music that appears and disappears on a predictable schedule. Commercial streaming services have this data, they use it, and it's among the more intimate behavioural datasets a company can hold.
Self-hosted Navidrome:
- Your music files — on your disk.
- Your index and play history — in your SQLite database, on your disk.
- Streaming — from your server to your device.
- Artist metadata and artwork requests to Last.fm, Spotify, Deezer, or ListenBrainz, which reveal what's in your library.
- Anonymous insights, if the collector is enabled.
One more: if you enable Last.fm scrobbling, you're deliberately sending your play history to Last.fm. That's a fine choice — just make it a choice.
9. Navidrome vs Jellyfin vs Plex vs Spotify
| | Navidrome | Jellyfin | Plex | Spotify |
|---|---|---|---|---|
| Content | Audio only | Audio + video | Audio + video | Catalogue |
| License | GPL-3.0 | GPL-3.0 | Proprietary | Proprietary |
| Resource use | Very light | Moderate | Moderate | N/A (cloud) |
| Mobile client | Third-party (Subsonic) | Official | Official | Official |
| Provides content | No | No | No (some free) | Yes |
| Setup difficulty | Low | Medium | Low | Trivial |
The rule: Navidrome for music, Jellyfin for video. Jellyfin can serve music, but its music experience is weaker, and it carries substantial transcoding overhead that a Pi-class device struggles with. Navidrome is dramatically lighter — it will run alongside a dozen other services without complaint.
Against Spotify, the comparison is category error rather than competition: one is a delivery mechanism for files you own, the other is a licensed catalogue. Only one of them survives your cancelling the subscription.
10. Who Should Not Self-Host Navidrome
- You don't own music files. Wait until you do.
- You mainly want discovery. Navidrome has none. Keep a streaming subscription for that.
- You want one app for music and video. Use Jellyfin.
- You need an official, supported mobile client. Third-party only here.
- Your tags are a mess and you won't fix them. The experience will be frustrating.
11. Getting Started
A realistic path:
1. Inventory your music first. How many files? What formats? Where are they? If the answer is "scattered across three old hard drives," consolidate before installing anything.
2. Fix your tags with MusicBrainz Picard. Do this once, properly, and everything downstream is better forever.
3. Deploy with Docker, matching the UID to your file owner, mounting music read-only, and disabling external services.
4. Let the initial scan finish before judging anything. Large libraries take real time on first import.
5. Install a mobile client — Symfonium on Android, Amperfy or play:Sub on iOS — and point it at your server.
6. Configure transcoding with a lower bitrate for cellular.
7. Add users for household members so play counts stay separate.
8. Set up remote access via VPN, not port forwarding.
9. Back up ./data — that's your playlists, favourites, and history. The music itself should be backed up separately.
Making It Actually Feel Like a Streaming Service
The difference between "a folder browser with a play button" and "something I actually use daily" comes down to three things, none of which are automatic.
One, metadata quality. Navidrome reads embedded tags, not filenames. 01 - Track.mp3 with no tags is an anonymous row in your library. Run MusicBrainz Picard over your collection once — it matches files against the MusicBrainz database and writes proper artist, album, year, track number, and artwork. A weekend of tagging transforms the entire experience. Do it before the first scan, not after.
Two, smart playlists. Navidrome supports dynamic playlists defined by rules rather than fixed track lists: "all tracks added in the last 60 days," "five-star songs not played in six months," "everything from the 1990s." This is the closest thing to algorithmic discovery you'll get, and it's surprisingly good at surfacing music you forgot you owned. Set up three or four on day one.
Three, artwork and artist images. Album art embedded in tags is used automatically; artist images are fetched from external sources, which means enabling that feature sends requests to third parties. If you want artist images without the outbound calls, you can drop artist.jpg files into artist directories manually. Slower, but fully local.
Also worth doing: set your library scan schedule (hourly is reasonable) and understand that Navidrome watches for filesystem changes too, so dropping new files into the folder triggers an incremental scan rather than a full re-index.
Running on Modest Hardware
Navidrome's resource profile is one of its genuine strengths. It's a single Go binary with SQLite; idle memory sits in the low hundreds of megabytes, and it runs happily on a Raspberry Pi 4 or an old mini-PC that would struggle to boot a modern browser.
Practical guidance:
- Raspberry Pi 4 (4 GB) or better is plenty for a personal library and a handful of users.
- Store the music on a USB SSD, not the SD card, if you're on a Pi. Constant reads will kill an SD card, and losing your music library to card failure is a miserable way to learn this.
- Put the
./datadirectory on reliable storage too — that's your database, playlists, and artwork cache. - Transcoding is the expensive part. Opus and MP3 conversion is CPU work; a Pi can handle two or three simultaneous streams comfortably, more if you lower bitrates. If you have many concurrent users, pre-transcode or use a beefier host.
- Initial scan is the slow part. First import on a large library over USB2-connected storage can take hours. Let it finish before judging performance.
Backups: Two Different Things
A Navidrome install has two categories of data with very different replacement costs, and people usually back up the more replaceable one.
Your music files. Irreplaceable if you ripped them from CDs you no longer own, bought as downloads, or inherited. These need real backup: an offsite copy, or at minimum a second disk. A single drive holding your only copy of a 15-year collection is one power surge from silence.
The ./data directory. Contains your SQLite index, playlists, favourites, play counts, and artwork cache. Losing it is annoying rather than catastrophic — you'd rescan and lose your listening history — but playlists and play counts accumulate meaning over years, so it's worth protecting.
A simple approach:
# Stop the container for a consistent SQLite snapshot
docker compose stop navidrome
tar czf navidrome-data-$(date +%F).tgz ./data
docker compose start navidrome
Copy that archive somewhere other than the same machine. If you're already running Restic, Borg, or Kopia, add ./data to the paths it covers and stop hand-rolling this.
Note that your music library should be backed up independently of Navidrome — a backup tool pointing at the same directory is the right answer, not a Navidrome-specific feature. The server is replaceable in ten minutes; the files are not.
12. Where the Music Actually Comes From
This is the question every Navidrome write-up glosses over, and it is the one that decides whether your server is a joy or an empty room.
CDs you already own. If you have a shelf of them, ripping is the highest-quality source available to you and it is a solved problem: Exact Audio Copy on Windows, abcde or ripit on Linux, XLD on macOS. Rip to FLAC once, losslessly, and generate your lossy copies from that master forever. The tedious part is tagging, not ripping, and it is worth doing properly the first time because you will never want to redo it.
Bandcamp and direct artist sales. The healthiest path, and the one that actually pays musicians. Bandcamp downloads are DRM-free by default and usually offered in FLAC. You buy the album, you own the file, and unlike a streaming licence the file survives the artist leaving the platform.
Old downloads and inherited drives. Most people's real library is this: a decade of accumulated MP3s, some at 128 kbps, some mislabelled, some from sources they would not admit to. Navidrome will serve it faithfully. The question is whether you want to — a library of badly encoded, badly tagged files is a library you will not enjoy browsing, and no server fixes that.
YouTube ripping and similar. I am not going to pretend this does not happen. It violates the terms of the platform, it produces variable and often mislabelled audio, and the "320 kbps" file you ended up with was frequently upscaled from something worse. If you are building a library you intend to keep for a decade, this is the wrong foundation.
The honest framing: Navidrome does not solve music acquisition, and it does not pretend to. It solves access to music you have. If the answer to "where do my files come from" is "nowhere yet," the correct sequence is to spend a few months buying albums you actually love — Bandcamp Friday sales make this cheaper than a subscription — and set up the server when you have a library worth serving. Installing Navidrome first and hunting for files second produces a server you abandon.
There is also a pleasant side effect nobody expects: owning files changes listening. When the catalogue is finite and chosen, you listen to whole albums rather than shuffling an infinite recommendation feed. Whether that is a feature depends on what you want from music, but it is a real and frequently reported shift.
13. Choosing a Mobile Client (Since There Isn't an Official One)
Navidrome has no first-party mobile app, which means your daily experience is determined by a third-party choice you have to make deliberately. This is the single highest-leverage decision in the whole setup — more than hardware, more than transcoding — because it is the interface you touch every day.
All of these work because Navidrome speaks the Subsonic API, a de facto standard that has been reverse-engineered and reimplemented for fifteen years. Any Subsonic-compatible client will talk to it, which is also why being locked out of Navidrome specifically is close to impossible.
On Android, Symfonium is what most people converge on. It is paid, it is actively maintained, and it does the things that matter: offline caching with per-playlist download rules, gapless playback, ReplayGain, a proper queue, Chromecast and Android Auto support, and scrobbling to Last.fm or ListenBrainz. Ultrasonic and DSub are the credible free alternatives, and Tempo exists if you want something minimal.
On iOS the picture is thinner, which is worth knowing before you commit: Amperfy, play:Sub, and Substreamer are the usual answers, all with rougher edges than their Android counterparts. If your household is entirely iPhone, budget patience here.
On desktop, Sonixd is a solid cross-platform client, though most people just use Navidrome's own web interface, which is good enough to be the primary interface rather than a fallback.
What to check before committing to a client:
- Does it cache offline, and can you automate it? If your commute goes through dead zones, a client without real offline downloads is useless to you.
- Does it support the transcoding profile you plan to use? Some clients request specific formats; mismatches show up as "file cannot be played."
- Is it actively maintained? Check the last release date. Abandoned Subsonic clients are a genre, and they tend to break on new Android versions rather than on new Navidrome versions.
- Does it scrobble where you want? If your listening history matters to you, confirm Last.fm or ListenBrainz support before you generate six months of plays that go nowhere.
14. Transcoding in Practice: Codecs, Bitrates, and CPU
Transcoding is what makes a home library usable on a phone with a limited data plan, and it is also the only part of Navidrome that will make your server's CPU notice.
The mental model is simple: Navidrome stores and serves your files as they are, and converts them on the fly when a client asks for a lower bitrate. A FLAC album played on your home network should stream untouched. The same album played on a phone over LTE should arrive as an Opus or MP3 stream at a bitrate you chose — a fifth of the data, imperceptibly different through a car stereo.
Opus is the right default for modern clients. At 96–128 kbps it is transparent for most listeners and materially better than MP3 at the same rate. Older or more conservative clients fall back to MP3, which every device on earth handles. Set per-player profiles rather than one global setting: high quality on Wi-Fi, aggressive saving on mobile data.
CPU cost scales with simultaneous streams, not library size. One or two transcodes are trivial even on a Raspberry Pi. A dozen concurrent transcodes on a Pi will fall over. If you routinely have many simultaneous listeners, either pre-transcode a lossy mirror of your library alongside the FLAC master — a one-time batch job with ffmpeg — or move to hardware with more headroom. Pre-transcoding also has the pleasant side effect of making your server behave identically under load, with no CPU spikes during peak listening.
Pre-transcoding is underrated in general. A parallel directory tree of 128 kbps Opus, generated once and refreshed when you add albums, costs disk — which is cheap — and buys you a server that never transcodes at all. For a household of four, this removes the last real performance question.
Two things that surprise people: transcoding requires ffmpeg to be present (the official container image includes it, bare-metal installs sometimes do not), and transcoding does not change your files. It is a stream, generated per request, cached briefly. Your FLAC master is untouched, which is exactly the property you want.
15. Getting to It From Outside Your House
A music server you can only reach from your own Wi-Fi is a music server you will use less than you expect. The interesting question is how to expose it without handing the internet a new attack surface.
The wrong answer is port-forwarding. Opening a port on your router and pointing a DNS name at your home IP puts a Go binary that parses untrusted media files directly on the internet, and it advertises your home IP to anyone who finds it. If you also skip TLS, your password crosses the network in clear text. This works, and people do it, and it is the setup that ends up in a breach disclosure.
The right answer depends on who needs access. For yourself and your household, a mesh network is simpler and strictly safer: put the server on your tailnet — Headscale if you want to own the control plane — and the app reaches navidrome.your-tailnet.ts.net as if it were local, with no public port at all. This is what I would do, and it takes less time than configuring a reverse proxy correctly.
If you need to share with people who will not install a VPN, put Navidrome behind a reverse proxy with automatic TLS — Traefik does this with a few labels — and add authentication in front if the audience is wider than people you trust. Note that Navidrome's own login is the only gate it ships with; anything more sophisticated is your reverse proxy's job.
Regardless of which path you take, two things are non-negotiable:
Change the first-run admin password immediately. Navidrome creates an admin account on first launch and prints the generated password to the log. Leaving it in place means leaving an administrator credential that anyone who reaches the login page can guess from the documentation.
Turn off external metadata fetching if you self-host for privacy. Artist images and biographies come from Last.fm, Spotify, Deezer, and ListenBrainz by default, which means outbound requests describing your library. For most people this is a reasonable trade. If the reason you self-host is that you do not want third parties knowing what you listen to, it is a contradiction you should resolve explicitly, not by accident.
16. Troubleshooting: The Five Things That Go Wrong
Files added to disk never appear. Almost always permissions or a scan that has not run. If you are using Docker, the container reads your music as a specific UID; if that user cannot read the directory, the scanner finds nothing and reports success. Check with docker exec into the container and try to ls the mount. Then confirm the scan schedule — Navidrome watches the filesystem, but a large drop or a network mount can require a manual full scan.
Everything shows up as "Unknown Artist." Your tags are empty or malformed. Navidrome reads embedded metadata, not filenames, and it cannot invent what is not there. Run MusicBrainz Picard over the collection. There is no shortcut for this and no setting that fixes it.
Album art is missing. Either it is not embedded in the files, or you have disabled external fetching and not supplied local images. Embedding art into tags at tagging time is the durable fix; dropping cover.jpg into album directories also works.
"File cannot be played" on mobile but fine on desktop. A transcoding problem: ffmpeg missing, a codec the client cannot handle, or a client requesting a format Navidrome is not configured to produce. Check the server log while attempting playback — it names the transcode command and usually the failure.
Play counts and favourites vanished after an upgrade. You replaced or lost the ./data directory. The database lives there; if it was on ephemeral storage or excluded from a volume mount, everything derived — playlists, history, favourites — goes with it. This is the single most common self-inflicted Navidrome injury, and it is entirely a Docker volume mistake rather than a Navidrome problem.
17. Three Setups Worth Copying
The personal archive. One Pi 4 with a USB SSD, a few hundred albums in FLAC, Navidrome in Docker, Symfonium on your phone with offline caching for your commute, and the whole thing reachable over your tailnet. Total cost if you already own the drive: whatever the Pi costs. This is the setup that makes a 15-year-old music collection feel current again.
The household server. The same box, but with per-user libraries: your music for everyone, an audiobook directory for specific accounts, a children's folder that is the only thing visible on the kids' tablet. Everyone keeps their own play counts and playlists. External metadata disabled, because at that point you are making a privacy decision for other people. This is where Navidrome's multi-user support stops being a bullet point and becomes the reason it works.
The small shared server. A VPS or a box at a friend's place, a handful of users, Navidrome behind Traefik with automatic TLS, and authentication handled by a real identity provider so you are not managing another password database. Pre-transcode a lossy mirror, because a VPS has less CPU than you think. This is the most work of the three and the most likely to be worth it if your group has a shared collection that none of you wants to duplicate.
What all three have in common: the music lives on a disk you control, in a format that will still be readable in twenty years, and nobody is compiling a profile of what you played at 3 a.m.
18. The Verdict
Navidrome is the best self-hosted music server available, and it wins by being disciplined about scope. It does one thing — serve your music library well — and it does it on hardware you'd otherwise retire. The Subsonic API compatibility means you're not stuck with one mediocre client. Transcoding makes it practical on mobile. Multi-user support makes it work for a household. And GPL-3.0 with no paid tier means the project has no incentive to hold features back.
The limitation is structural rather than technical: it needs you to own music. For people with real libraries, that's not a limitation at all — it's the point. For people whose entire listening life is a Spotify account, Navidrome will be an empty room.
If you have a drive full of music you've spent years curating, this is how you make it listenable everywhere again — on your phone, in your car, at work — without a monthly bill and without telling anyone what you played at 3 a.m.
Related
- Headscale: The Open-Source Tailscale Control Server That Puts Your Mesh VPN Back in Your Hands — reach your music library from anywhere without opening a port.
- Traefik: The Reverse Proxy That Configures Itself While You Sleep — put Navidrome behind TLS with automatic certificates.
- Syncthing: The File Sync That Never Asks a Cloud for Permission — get newly acquired music onto your server automatically.
Comments (0)
No comments yet. Be the first to comment!