Navidrome is a lightweight, open-source music server: a web player, multiple users, playlists and smart playlists, plus compatibility with the Subsonic API, so dozens of mobile and desktop apps can stream your collection. It’s written in Go, uses very little memory, and handles libraries of hundreds of thousands of tracks. That makes it ideal for a small VPS.
Requirements
- Any small VPS: 1 vCPU and 512 MB–1 GB RAM is enough for most personal libraries.
- Storage for your music. FLAC libraries can be large. See storage VPS.
- Docker (or the single binary).
Stream only music you own or have the rights to.
Install with Docker
# /opt/navidrome/compose.yaml
services:
navidrome:
image: deluan/navidrome:latest
user: 1000:1000
restart: unless-stopped
ports:
- "127.0.0.1:4533:4533"
environment:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_BASEURL: ""
ND_ENABLESHARING: "true"
volumes:
- /opt/navidrome/data:/data
- /srv/music:/music:ro
sudo mkdir -p /opt/navidrome/data && sudo chown -R 1000:1000 /opt/navidrome
cd /opt/navidrome && docker compose up -d
The music folder is mounted read-only. Navidrome never modifies your files.
On first visit, create the admin account. Do this immediately after starting, or keep the port closed until you have.
Organise your music
Navidrome relies on embedded tags (artist, album, album artist, track number, year, genre and cover art), not folder names. Clean tags give a clean library. Tools like MusicBrainz Picard or beets tag and organise collections automatically. Folder structure is up to you. Artist/Album/01 - Title.flac is common.
Copy music to the server with rsync or SFTP:
rsync -avh --progress ~/Music/ user@your-vps:/srv/music/
See rsync.
HTTPS with Nginx
server {
server_name music.example.com;
location / {
proxy_pass http://127.0.0.1:4533;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
# listen 443 ssl; certbot --nginx -d music.example.com
}
See Nginx reverse proxy and Let’s Encrypt.
Apps
Thanks to the Subsonic API, many clients work with Navidrome:
- Android: Symfonium, Ultrasonic, DSub, Tempo
- iOS: play:Sub, Amperfy, substreamer
- Desktop: Feishin, Sonixd, Supersonic
- Web: Navidrome’s built-in player
Connect with your server URL (https://music.example.com), username and password. Most apps support offline caching for mobile listening.
Transcoding
To save mobile data, Navidrome can transcode on the fly (e.g. FLAC → Opus 128 kbit/s) using ffmpeg, which the Docker image includes. Configure transcodings and per-player limits in the UI (Settings → Players). Opus gives excellent quality at low bitrates. Transcoding uses CPU, but audio is cheap compared with video.
Users, sharing and scrobbling
- Multiple users, each with their own playlists, favourites and play counts.
- Sharing: create public share links for albums or playlists (if
ND_ENABLESHARINGis on). - Scrobbling to Last.fm or ListenBrainz, configured per user.
Backups and updates
- Back up
/opt/navidrome/data. It contains the database (users, playlists, play counts). The music itself should have its own backup. See backup strategy. - Update:
docker compose pull && docker compose up -d. See updating self-hosted apps.
Bandwidth
Streaming FLAC uses roughly 1 Mbit/s per listener, and Opus 128k about 0.13 Mbit/s. Even heavy personal use rarely matters for a VPS’s monthly transfer, but check with vnStat if you share widely.
Quick reference
| Task | Command / setting |
|---|---|
| Start | docker compose up -d |
| Port | 4533 (behind Nginx) |
| Music folder | mounted read-only at /music |
| Rescan interval | ND_SCANSCHEDULE=1h |
| Data to back up | /data volume |
| Apps | Any Subsonic-compatible client |
Related: Audiobookshelf and Jellyfin vs Plex.