How to Self-Host Navidrome: Music Streaming Server (Spotify Alternative) 2026
TL;DR
Navidrome (GPL 3.0, ~11K GitHub stars, Go) is a self-hosted music streaming server that turns your local music library into a Spotify-like streaming service. It's Subsonic API compatible, which means it works with every Subsonic client — iOS, Android, desktop, web. Stream FLAC, MP3, AAC, and any audio format to any device. Spotify Premium costs $9.99/month and only has what they license; Navidrome streams your own lossless library for free.
Key Takeaways
- Navidrome: GPL 3.0, ~11K stars — self-hosted Subsonic music server, all formats
- Subsonic API compatible: Works with Symfonium, DSub, Feishin, Foobar2000, and more
- All formats: FLAC, MP3, AAC, OGG, OPUS, ALAC — streams lossless to compatible clients
- Transcoding: Converts FLAC → MP3 on-the-fly for low-bandwidth connections
- Smart playlists: Dynamic playlists based on rules
- Multi-user: Each user has their own play count, favorites, playlists
Navidrome vs Funkwhale vs Spotify
| Feature | Navidrome | Funkwhale | Spotify |
|---|---|---|---|
| License | GPL 3.0 | AGPL 3.0 | Proprietary |
| Cost | Free | Free | $9.99/mo |
| Lossless (FLAC) | Yes | Yes | No (max 320kbps) |
| Own library | Yes | Yes | No (their catalog) |
| Subsonic API | Yes | Yes (partial) | No |
| Smart playlists | Yes | No | Yes |
| Social features | No | Yes (federation) | Yes |
| Transcoding | Yes | Yes | — |
| iOS apps | Via Subsonic | Via Subsonic | Official |
| RAM | ~50MB | ~200MB | — |
| GitHub Stars | ~11K | ~1.5K | — |
Part 1: Docker Setup
# docker-compose.yml
services:
navidrome:
image: deluan/navidrome:latest
container_name: navidrome
restart: unless-stopped
user: "1000:1000"
ports:
- "4533:4533"
volumes:
- navidrome_data:/data
- /path/to/music:/music:ro # Your music library (read-only)
environment:
ND_SCANSCHEDULE: "1h" # Scan for new music every hour
ND_LOGLEVEL: "info"
ND_SESSIONTIMEOUT: "24h"
ND_BASEURL: ""
ND_SPOTIFY_ID: "" # Optional: Spotify API for artist images
ND_SPOTIFY_SECRET: ""
ND_LASTFM_ENABLED: "true" # Optional: Last.fm scrobbling
ND_LASTFM_APIKEY: ""
ND_LASTFM_SECRET: ""
ND_ENABLEGRAVATAR: "true" # User avatars from Gravatar
ND_DEFAULTLANGUAGE: "en"
ND_DEFAULTTHEME: "Dark"
volumes:
navidrome_data:
docker compose up -d
Visit http://your-server:4533 → create admin account.
Part 2: HTTPS with Caddy
music.yourdomain.com {
reverse_proxy localhost:4533
}
Part 3: Music Library Organization
Navidrome follows standard music tagging conventions:
/music/
Artist Name/
Album Name (2020)/
01 - Track Title.flac
02 - Track Title.flac
cover.jpg ← Album art
Various Artists/
Compilation (2019)/
01 - Artist - Track.mp3
Tagging matters: Navidrome reads metadata from ID3 tags (MP3), FLAC tags, etc.
Recommended taggers:
- beets (command line, automated)
- MusicBrainz Picard (GUI, accurate)
- Mp3tag (Windows GUI)
Part 4: Connect Mobile Apps
Android — Symfonium (Recommended)
Symfonium (~$6) is the best Android Navidrome client:
- Add media provider → Navidrome / OpenSubsonic
- Server URL:
https://music.yourdomain.com - Username + password
- Downloads for offline, CarPlay support, album art
Android — DSub (Free)
DSub — free, open source:
- Server URL:
https://music.yourdomain.com - Username + password
- Version: Subsonic 1.15 or higher
iOS — Amperfy
Amperfy (free, open source):
- Add Navidrome server
- URL + credentials
- Downloads, queue management, background playback
Desktop — Feishin
Feishin is a beautiful cross-platform desktop app:
# macOS/Linux/Windows:
# Download from GitHub releases
Configure → Navidrome server URL + credentials.
Web Player (Built-in)
Navidrome includes its own web player at https://music.yourdomain.com:
- Browse by Artist/Album/Genre
- Create playlists
- Queue management
- Last.fm integration
Part 5: Transcoding
For clients that don't support FLAC or for low-bandwidth connections:
environment:
ND_TRANSCODINGENABLED: "true"
# Transcoding is configured per-user in Settings or by format
Per-user transcoding settings:
- User → Personal Settings → Max Bit Rate
- Set to 128/192/320 kbps — Navidrome transcodes FLAC → MP3 on-the-fly
Or configure globally:
# navidrome.toml
TranscodingCacheSize = "100MiB"
Part 6: Last.fm Scrobbling
Track what you listen to with Last.fm:
- Settings → External Integrations → Last.fm
- Get API key from last.fm/api
- Enable per-user in Personal Settings → Last.fm link
Or use ListenBrainz (open alternative to Last.fm):
environment:
ND_LISTENBRAINZ_ENABLED: "true"
Part 7: Multi-User Setup
Add users with different permissions:
- Settings → Users → New User
- Set: username, password, role
- Roles:
- Admin: Full access including settings
- Regular: Browse and play only
- Download: Can download tracks
Each user has their own:
- Play history and statistics
- Playlists
- Favorites (starred tracks)
- Last.fm/ListenBrainz account
Part 8: Smart Playlists
Create dynamic playlists using the Navidrome query language:
# Recently added albums:
albumDate after -30 days
# 5-star tracks:
starred = true AND rating = 5
# Unplayed music:
playCount = 0
# Jazz released in the 60s:
genre = "Jazz" AND albumDate > 1960 AND albumDate < 1970
# Long tracks (20+ minutes):
duration > 1200
Part 9: Beets Integration (Auto-Tagging)
beets automatically tags and organizes your music from MusicBrainz:
# Install beets:
pip install beets
# config.yaml
directory: /music
library: /data/beets/musiclibrary.db
import:
copy: yes
move: no
plugins: fetchart embedart lastgenre
# Import and tag your music collection:
beet import /path/to/untagged/music/
After beets tags everything properly, Navidrome's metadata will be perfect.
Maintenance
# Update Navidrome:
docker compose pull
docker compose up -d
# Trigger manual library scan:
# Admin → Library → Scan Now
# Logs:
docker compose logs -f navidrome
# Backup (SQLite database):
tar -czf navidrome-backup-$(date +%Y%m%d).tar.gz \
$(docker volume inspect navidrome_navidrome_data --format '{{.Mountpoint}}')
See all open source music and media tools at OSSAlt.com/categories/media.