- DIY
- A
Navidrome: setting up your own streaming server in one evening
Set up your own streaming server to avoid content restrictions. Navidrome with Docker can be set up in one evening on any Linux, works with all Subsonic clients.
Navidrome is an open-source streaming server. It reads a music folder, serves content via browser and apps.
It works via Subsonic API, so it's compatible with dozens of pre-built clients across all platforms.
Installed via Docker: a single
docker-compose.yml, five minutes, done.Runs on any Linux device: Raspberry Pi, NAS, VPS, old laptop.
Supports multiple users, playlists, scrobbling, transcoding.
Why you need this
Streaming services are convenient as long as everything is stable. Then rights holders start removing tracks from platforms. Then internal censorship hits — lyrics are censored, tracks are deleted. The platform isn't to blame here — it just does what it's told by external parties. But the end result is the same: you don't control your own library.
Navidrome solves a specific problem: take a music folder and turn it into a full-fledged streaming service — with a web interface, mobile apps, search, and playlists. No subscriptions, no reliance on external services.
I run mine on a Raspberry Pi 5 — I'll cover hardware selection separately in the next section.
What is Navidrome
Navidrome is an open-source media server written in Go. Licensed under GPL-3.0.
Out-of-the-box features:
Supports FLAC, MP3, AAC, ALAC, OPUS, OGG and other formats
Web interface — a full-featured player in your browser
Subsonic API v1.16.1 — compatible with dozens of third-party clients
Multi-user mode with permission controls
Smart Playlists — filter by genre, rating, date added
Scrobbling to Last.fm and ListenBrainz
On-the-fly transcoding (FLAC → MP3 to save bandwidth)
Metadata fetching: artist biographies, similar artists (via Last.fm API)
Scheduled automatic library scanning
What's missing:
DLNA/UPnP control (requires a separate service)
Built-in podcast manager
Requirements
Minimum:
Linux (x86_64, ARM64, ARMv7)
Docker + Docker Compose
Music folder
Navidrome runs on almost any hardware: Raspberry Pi 2+, any Docker-enabled NAS, VPS, old laptop. Memory usage during operation is around 80-120 MB.
Installation via Docker
The easiest and recommended method.
1. Install Docker
If Docker is not already installed:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
Verify:
docker --version
docker compose version
2. Create docker-compose.yml
mkdir -p ~/navidrome && cd ~/navidrome
docker-compose.yml:
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
user: "1000:1000"
ports:
- "4533:4533"
restart: unless-stopped
environment:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: ""
volumes:
- "./data:/data"
- "/path/to/music:/music:ro"
/path/to/music is the absolute path to your music folder. :ro means read-only; Navidrome only reads files and does not modify them.
3. Run
docker compose up -d
Open http://localhost:4533 in your browser after 30–60 seconds
On first launch, Navidrome will prompt you to create an administrator account. After that, the initial library scan will start.
Music Library Structure
Navidrome reads tags from files (ID3 for MP3, Vorbis Comments for FLAC). Folder structure affects how content is displayed, but it is not mandatory.
Recommended structure:
/music/
├── Artist Name/
│ ├── 2019 - Album Title/
│ │ ├── 01 - Track Name.flac
│ │ ├── 02 - Track Name.flac
│ │ └── cover.jpg
│ └── 2023 - Another Album/
│ └── ...
└── Various Artists/
└── Compilation Name/
└── ...
Placing the year before the album title ensures correct chronological sorting.
Cover art: Navidrome reads cover.jpg / folder.jpg alongside tracks, or embedded cover art from file tags. Embedded tags take priority.
Force Rescan
Scheduled scans are configured via ND_SCANSCHEDULE (for example, 1h, @daily, @weekly).
To force a scan via the web interface: Settings → Library → Scan Now.
Or via the Subsonic API:
curl -u admin:password \
"http://localhost:4533/rest/startScan?v=1.16.1&c=myclient&f=json"
Subsonic API — why it matters
Subsonic is a 2009 protocol, but it is the one that unites the entire self-hosted audio ecosystem. Navidrome implements Subsonic API version 1.16.1.
This means: any client written for Subsonic/Airsonic/Funkwhale works with Navidrome without changes. There are dozens of such clients: for iOS, Android, macOS, Windows, Linux, web.
Basic URL for connecting clients:
http://:4533
The login and password are the same as in the web interface.
Useful environment variables
The full list is in the documentation. Most useful ones:
Variable | Default value | Description |
|---|---|---|
|
| Scan schedule |
|
| Log level: |
|
| Session lifetime |
|
| On-the-fly transcoding |
|
| Web interface theme |
| — | Last.fm API key for metadata and scrobbling |
|
| Scrobbling to ListenBrainz |
|
| Playlists in sidebar |
To enable Last.fm (artist biographies, similar artists, scrobbling), you need a free API key from their website:
environment:
ND_LASTFM_APIKEY: "your_api_key"
ND_LASTFM_SECRET: "your_api_secret"
ND_LASTFM_ENABLED: "true"
External access
By default, Navidrome only listens locally on port 4533. To access it from your phone while on the go, you need either port forwarding or a VPN.
I use Tailscale — a mesh VPN that doesn't require dealing with ports and routers. More details on setting up remote access will be in the next part about hardware and networking.
Clients
Since Navidrome implements the Subsonic API — it works with any Subsonic client. What I use myself:
Mac: kōan — a terminal client with a direct path to an external DAC
iPhone: Kolis Music
Android / hi-fi player: Symfonium
I plan to cover this topic in more detail in future posts.
Update
Navidrome is actively developed. To update to the latest version:
cd ~/navidrome
docker compose pull
docker compose up -d
Data is stored in ./data/ — it is not affected when updating the image.
Conclusion
Navidrome solves the "your own streaming" task with minimal resources:
One
docker-compose.yml— the service is up and runningSubsonic API — clients for any platform without additional setup
Uses ~100 MB of RAM, runs on even the most modest hardware
Actively maintained, documentation is up to date
Write comment