Zum Inhalt

Self-Hosting Music Streaming: Navidrome on Debian Linux (Subsonic API, FLAC & On-the-Fly Opus)

Executive Summary: Written in Go with a React Material UI frontend, Navidrome is the undisputed modern gold standard for self-hosted music streaming. Consuming less than 40 MB of RAM at idle, Navidrome indexes hundreds of thousands of FLAC, ALAC, Opus, and MP3 tracks in seconds, implements the OpenSubsonic REST API (making it compatible with dozens of native iOS, Android, and desktop clients), and performs on-the-fly FLAC → Opus audio transcoding for mobile listening over cellular networks.

  • Featherweight Go Engine


    Written in compiled Go backed by an embedded SQLite database—starts in < 200 ms and runs effortlessly even on a Raspberry Pi.

  • OpenSubsonic API Ecosystem


    Connect premier native apps: Symfonium (Android), Amperfy / Play:Sub (iOS/CarPlay), Supersonic / Feishin (Linux Desktop).

  • Lossless FLAC & Mobile Opus


    Stream bit-perfect 24-bit/96kHz FLAC on home Wi-Fi and transcode on-the-fly to 128 kbps Opus when driving on mobile data.

  • Smart Playlists & Multi-User


    Build dynamic rule-based .nsp Smart Playlists, preserve per-user play counts/favorites, and normalize volume via ReplayGain.


1. Navidrome Streaming & Transcoding Architecture

Navidrome mounts your music directory strictly read-only (:ro)—it never modifies or reorganizes your audio files or embedded ID3/Vorbis tags on disk.

%%{init: {'flowchart': {'wrappingWidth': 600}}}%%
flowchart TB
    FLAC["💿 Lossless Audio Pool<br/>/srv/media/music (:ro)<br/>(FLAC / MP3 / M3U8)"]
    NAVI["🎵 Navidrome Daemon (Go)<br/>127.0.0.1:4533<br/>(SQLite Tag Index + FFmpeg)"]
    PROXY["🔒 Reverse Proxy (TLS 1.3)<br/>music.nejat-hakan.de"]
    APP["📱 OpenSubsonic Clients<br/>Symfonium / Feishin / Web UI"]

    FLAC -->|"Inotify + Periodic Scan"| NAVI
    NAVI <-->|"Bit-Perfect or Opus Stream"| PROXY
    PROXY <--> APP

2. Production Container Deployment (compose.yaml)

Create the persistent /data directory for Navidrome's SQLite index and artwork cache, then deploy the official deluan/navidrome container:

# File: /opt/navidrome-ops/01_prepare_dirs.sh
sudo mkdir -p /srv/containers/navidrome/data
sudo chown -R 1000:1000 /srv/containers/navidrome
# File: /srv/containers/navidrome/compose.yaml
services:
  navidrome:
    image: docker.io/deluan/navidrome:latest
    container_name: navidrome
    user: "1000:1000"
    restart: unless-stopped
    ports:
      - "127.0.0.1:4533:4533/tcp"
    environment:
      # Scan library every 1 hour (in addition to real-time filesystem watcher)
      ND_SCANSCHEDULE: 1h
      ND_LOGLEVEL: info
      ND_SESSIONTIMEOUT: 24h
      ND_BASEURL: ""
      # Security & Privacy: Disable public sharing links if not needed, and encrypt subsonic passwords
      ND_ENABLESHARING: "false"
      ND_PASSWORDENCRYPTIONKEY: "Replace_With_32_Byte_Random_Hex_Secret_2026!"
      # Transcoding cache size for mobile Opus/MP3 streams
      ND_TRANSCODINGCACHESIZE: "500MB"
      ND_IMAGECACHESIZE: "500MB"
      # Enable ReplayGain metadata parsing
      ND_ENABLETRANSCODINGCONFIG: "true"
    volumes:
      - /srv/containers/navidrome/data:/data:rw
      - /srv/media/music:/music:ro

Generate a random 32-byte key for ND_PASSWORDENCRYPTIONKEY using openssl rand -hex 32 before starting with docker compose up -d.


3. Dynamic Smart Playlists (.nsp) & Opus Mobile Transcoding

One of Navidrome's killer features is JSON-defined Smart Playlists (.nsp). Simply drop a .nsp file into your /srv/media/music/playlists/ folder, and Navidrome automatically populates and updates the playlist on every scan:

// File: /srv/media/music/playlists/90s_rock_favorites.nsp
{
  "name": "90s Rock & Metal Favorites (Lossless)",
  "comment": "Auto-updated dynamic playlist of high-rated 1990s rock tracks",
  "all": [
    { "inTheRange": { "year": [1990, 1999] } },
    { "contains": { "genre": "Rock" } },
    { "gt": { "rating": 3 } }
  ],
  "sort": "random",
  "limit": 150
}

Configuring On-the-Fly Opus Cellular Transcoding

Why transcode FLAC (~900 kbps) to Opus (128 kbps) instead of legacy MP3 when listening on mobile data? Because the IETF Opus codec achieves transparent audiophile perceptual quality at 128 kbps while using 85% less mobile bandwidth! 1. In the Navidrome Web UI, navigate to Transcoding → New. 2. Name: Opus 128k Mobile | Target Format: opus | Default Bit Rate: 128 3. Command: ffmpeg -i %s -map 0:a:0 -b:a %bk -v 0 -c:a libopus -f opus -


Where to Go Next

Explore related self-hosted media and reverse proxy guides:

  • Jellyfin Video & Movie Server


    Complete your open-source entertainment stack with Jellyfin for movies and series.

    Jellyfin Guide

  • Immich Photo Management


    Self-host automated mobile photo/video backups with local AI facial and semantic search.

    Immich Guide

  • Caddy Reverse Proxy


    Expose Navidrome (127.0.0.1:4533) over HTTPS with automatic TLS 1.3 certificates.

    Caddy Guide