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_ENABLESHARING is 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.

  • Self-Hosting
  • Media
  • Docker