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

ND_SCANSCHEDULE

@every 1m (first run)

Scan schedule

ND_LOGLEVEL

info

Log level: error, warn, info, debug

ND_SESSIONTIMEOUT

24h

Session lifetime

ND_ENABLETRANSCODING

true

On-the-fly transcoding

ND_DEFAULTTHEME

Dark

Web interface theme

ND_LASTFM_APIKEY

Last.fm API key for metadata and scrobbling

ND_LISTENBRAINZ_ENABLED

false

Scrobbling to ListenBrainz

ND_MAXSIDEBARPLAYLISTS

10

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 running

  • Subsonic 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

Comments

    Also read