<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Navidrome – Serverküche</title><link>https://serverkueche.de/en/tags/navidrome/</link><description>Navidrome – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>en-US</language><managingEditor>feedback@serverkueche.de (Serverküche)</managingEditor><webMaster>feedback@serverkueche.de (Serverküche)</webMaster><copyright>2026 Serverküche</copyright><lastBuildDate>Thu, 17 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/en/tags/navidrome/index.xml" rel="self" type="application/rss+xml"/><item><title>Navidrome: Stream Your Own Music Like Spotify</title><link>https://serverkueche.de/en/tutorials/navidrome-stream-music/</link><pubDate>Thu, 17 Sep 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/navidrome-stream-music/</guid><description>Stream your music collection from anywhere – no subscription, no tracking: Navidrome behind Traefik, with app support via the Subsonic standard and backups.</description><content:encoded><![CDATA[<p>Your painstakingly assembled music collection sits on a hard drive while you pay for Spotify on the go? Navidrome turns your own files into a streaming service: a web interface, mobile apps, access everywhere – and nobody analyzes what you listen to.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>A personal music streaming server with <strong>Navidrome</strong> (v0.63.2) behind <a href="/en/tutorials/traefik-reverse-proxy/">Traefik</a>. By the end you browse your collection in the browser by album, artist and genre, stream on demand – and connect the app of your choice (Symfonium, DSub, play:Sub …) via the <strong>Subsonic standard</strong> to listen on the go too. Navidrome is remarkably resource-friendly (written in Go) and runs happily on a small VPS.</p>
<p>For <strong>audiobooks and podcasts</strong> it is the wrong tool, though: Navidrome thinks in albums and tracks, not chapters, and does not remember your listening position across devices. Use Audiobookshelf <span class="text-sm text-slate-500 dark:text-slate-400">(Tutorial expected in September)</span> for those – the two run side by side on the same server without trouble.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A server with <a href="/en/tutorials/traefik-reverse-proxy/">Traefik</a> running and <a href="/en/tutorials/docker-compose-basics/">Docker Compose</a></li>
<li>A <a href="/en/tutorials/connect-domain-to-server/">subdomain pointing at the server</a> – <code>YOUR_DOMAIN</code> below</li>
<li>Your music files (MP3, FLAC, …) with proper metadata (tags) – Navidrome builds the library from them</li>
</ul>
<div class="not-prose my-6 overflow-hidden rounded-xl border border-paprika-200 bg-paprika-50 dark:border-paprika-800 dark:bg-paprika-900/20"
     data-track-content data-content-name="Affiliate-Box · /en/tutorials/navidrome-stream-music/" data-content-piece="VPS 1000 G12.5">
  <div class="flex items-center justify-between border-b border-paprika-200 bg-paprika-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-paprika-700 dark:border-paprika-800 dark:bg-paprika-900/40 dark:text-paprika-300">
    <span>🍳 Recommendation</span>
    <span title="Links marked with * are affiliate links.">Ad</span>
  </div>
  <div class="flex flex-col gap-4 p-4 sm:flex-row sm:items-center sm:justify-between">
    <div>
      <p class="text-lg font-bold text-slate-900 dark:text-white">VPS 1000 G12.5</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">4 vCores · 8 GB RAM · 128 GB SSD</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">from €14.50/month</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">Navidrome is frugal; for large collections mostly the storage space matters.</p>
    </div>
    <a href="https://www.netcup.com/en/server/vps/vps-1000-g12.5-iv-24m-eu?ref=44083#vps-1000-g12.5-iv-12m-eu" rel="sponsored noopener" target="_blank"
   data-track-event="Affiliate|netcup: Affiliate-Box|VPS 1000 G12.5 · {page}"
   class="inline-flex shrink-0 items-center justify-center rounded-lg bg-paprika-600 px-5 py-2.5 font-semibold text-white transition-colors hover:bg-paprika-700">
  Go to netcup →
</a>

  </div><div class="px-4 pb-4"><div class="not-prose my-3 rounded-lg border border-herb-500/40 bg-herb-50 px-3 py-2 text-sm text-slate-700 dark:bg-herb-900/20 dark:text-slate-200">
  <p class="flex flex-wrap items-center gap-x-2 gap-y-1">
    <span>💶 <strong>€5 voucher</strong> for new netcup customers:</span>
    <button type="button" data-voucher-code data-track-voucher="36nc17844976032"
            title="Click to copy" class="cursor-pointer rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 hover:ring-2 hover:ring-herb-500/40 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</button>
    <span class="text-xs text-slate-500 dark:text-slate-400">(not for domains or VPS Lite)</span>
  </p>
  <p class="mt-1 text-xs text-slate-500 dark:text-slate-400">
    <a href="https://www.netcup.com/en/checkout/cart?ref=44083" rel="sponsored noopener" target="_blank"
       data-track-event="Affiliate|netcup: Gutschein einlösen|€5 · {page}"
       class="font-medium text-herb-800 underline underline-offset-2 hover:text-herb-900 dark:text-herb-400">Redeem in the cart →</a>
  </p>
</div></div>
</div>

<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-create-the-project">Step 1: Create the project</h3>
<p>Navidrome needs two folders: one for the music (read-only) and one for its database/index. Create the project:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p /opt/navidrome/data /opt/navidrome/music <span class="o">&amp;&amp;</span> <span class="nb">cd</span> /opt/navidrome
</span></span><span class="line"><span class="cl">chown -R 1000:1000 /opt/navidrome</span></span></code></pre></div>
</div>
<h3 id="step-2-get-the-music-onto-the-server">Step 2: Get the music onto the server</h3>
<p>Copy your music into the <code>music</code> folder – ideally cleanly structured (<code>Artist/Album/Track.mp3</code>). <code>rsync</code> over SSH is well suited for the transfer:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">rsync -av --progress ~/Music/ root@YOUR_SERVER_IP:/opt/navidrome/music/</span></span></code></pre></div>
</div>
<p>What matters is <strong>good metadata</strong>: Navidrome reads artist, album, title, year and cover from the files&rsquo; tags, not from the filenames. Poorly tagged files end up unsorted in the library.</p>
<h3 id="step-3-the-compose-file">Step 3: The Compose file</h3>
<p>Replace <code>YOUR_DOMAIN</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">navidrome</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">deluan/navidrome:0.63.2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;1000:1000&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">ND_MUSICFOLDER</span><span class="p">:</span><span class="w"> </span><span class="l">/music</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">ND_DATAFOLDER</span><span class="p">:</span><span class="w"> </span><span class="l">/data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">ND_SCANNER_SCHEDULE</span><span class="p">:</span><span class="w"> </span><span class="l">1h       </span><span class="w"> </span><span class="c"># look for new files hourly</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./data:/data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./music:/music:ro       </span><span class="w"> </span><span class="c"># mount the music read-only</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">proxy]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.enable=true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.navidrome.rule=Host(`YOUR_DOMAIN`)&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.navidrome.entrypoints=websecure&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.navidrome.tls.certresolver=le&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.services.navidrome.loadbalancer.server.port=4533&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">networks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">proxy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">external</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span></span></span></code></pre></div>
</div>
<p>The <code>:ro</code> on the music volume is deliberate: Navidrome should only read your files, never modify them. <code>ND_SCANNER_SCHEDULE: 1h</code> has it look for new music hourly.</p>
<h3 id="step-4-start-and-check-the-scan">Step 4: Start and check the scan</h3>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose up -d</span></span></code></pre></div>
</div>
<p>Navidrome scans the library on first start. You can follow it in the log:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose logs <span class="p">|</span> grep -i scan</span></span></code></pre></div>
</div>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Scanner: Completed processing folder audioCount=3 tracksImported=3
</span></span><span class="line"><span class="cl">Scanner: Finished scanning all libraries duration=279ms</span></span></code></pre></div>
</div>
<p><code>tracksImported</code> shows how many tracks were recognized. For large collections the first scan takes correspondingly longer.</p>
<h3 id="step-5-create-the-admin-account">Step 5: Create the admin account</h3>
<p>Open <code>https://YOUR_DOMAIN/</code>. On first access you create the administrator account:</p>
<p><figure class="my-6"><img src="/en/tutorials/navidrome-stream-music/nd-setup_hu_302a4bfe43073d34.webp" srcset="/en/tutorials/navidrome-stream-music/nd-setup_hu_5f1760b0564ba8c6.webp 480w, /en/tutorials/navidrome-stream-music/nd-setup_hu_302a4bfe43073d34.webp 768w, /en/tutorials/navidrome-stream-music/nd-setup_hu_8c5ab977702e1222.webp 1200w, /en/tutorials/navidrome-stream-music/nd-setup_hu_9de011cd6ebf11fb.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/navidrome-stream-music/nd-setup_hu_f284bb8551dd9e7c.webp"
    alt="The Navidrome first-run screen for creating the admin account" title="On first start you set the admin&#39;s username and password"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">On first start you set the admin&#39;s username and password</figcaption></figure></p>
<p>Pick a username and a strong password. Afterwards you land directly in your library.</p>
<h3 id="step-6-browse-the-library">Step 6: Browse the library</h3>
<p>The web interface shows your music by album, artist, genre and recently added – with cover grids and search:</p>
<p><figure class="my-6"><img src="/en/tutorials/navidrome-stream-music/nd-albums_hu_5220efd9394e6662.webp" srcset="/en/tutorials/navidrome-stream-music/nd-albums_hu_f17fd843efaf681d.webp 480w, /en/tutorials/navidrome-stream-music/nd-albums_hu_5220efd9394e6662.webp 768w, /en/tutorials/navidrome-stream-music/nd-albums_hu_e1583a7564aa7528.webp 1200w, /en/tutorials/navidrome-stream-music/nd-albums_hu_a215078083b825ef.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/navidrome-stream-music/nd-albums_hu_4e4044bd75f4f691.webp"
    alt="The Navidrome album overview with the recognized albums and artists" title="The library: albums with cover, artist and filter options"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The library: albums with cover, artist and filter options</figcaption></figure></p>
<p>Clicking an album opens the track list; double-clicking a track starts playback in the built-in player at the bottom:</p>
<p><figure class="my-6"><img src="/en/tutorials/navidrome-stream-music/nd-player_hu_9aa1291f921c829f.webp" srcset="/en/tutorials/navidrome-stream-music/nd-player_hu_308c889e67a20f9e.webp 480w, /en/tutorials/navidrome-stream-music/nd-player_hu_9aa1291f921c829f.webp 768w, /en/tutorials/navidrome-stream-music/nd-player_hu_38d593d38fd4bd0f.webp 1200w, /en/tutorials/navidrome-stream-music/nd-player_hu_5025c4847f7b480f.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/navidrome-stream-music/nd-player_hu_b6a450bebde6302a.webp"
    alt="An opened album with track list and the running player at the bottom" title="Album view with track list – the built-in player at the bottom is playing the first track"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Album view with track list – the built-in player at the bottom is playing the first track</figcaption></figure></p>
<h3 id="step-7-connect-mobile-apps-via-subsonic">Step 7: Connect mobile apps via Subsonic</h3>
<p>Navidrome speaks the <strong>Subsonic API</strong> – an established standard supported by many music apps. That&rsquo;s how you listen to your collection on the go with the app of your choice. In the app you enter:</p>
<ul>
<li><strong>Server:</strong> <code>https://YOUR_DOMAIN</code></li>
<li><strong>Username/password:</strong> your Navidrome account</li>
</ul>
<p>Recommended apps: <strong>Symfonium</strong> or <strong>Tempo</strong> (Android), <strong>play:Sub</strong> or <strong>substreamer</strong> (iOS). Create separate user accounts for family members in the Navidrome settings instead of sharing the admin account.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Transcoding saves mobile data
  </p>
  <div class="prose-kitchen text-sm">Navidrome can convert music to a lower bitrate while streaming (transcoding), e.g. for the road. You enable that per user or player in the settings under &ldquo;Transcoding&rdquo;. So you stream in full quality at home and data-efficiently on mobile – without touching the original files.</div>
</div>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong>The library stays empty.</strong> Either there are no files in the mounted <code>music</code> folder, or the permissions are wrong. Check: <code>docker compose logs | grep -i scan</code> shows <code>tracksImported</code>. If it&rsquo;s <code>0</code>, check the path and that the <code>music</code> folder is owned by UID 1000 (see <a href="/en/tutorials/linux-users-and-permissions/">Users &amp; permissions</a>).</p>
<p><strong>Tracks appear unsorted or without cover art.</strong> The files&rsquo; metadata is incomplete. Navidrome sorts by tags, not by filenames – re-tag the files (e.g. with Picard) and let Navidrome rescan.</p>
<p><strong>New music doesn&rsquo;t show up.</strong> The scan only runs hourly (<code>ND_SCANNER_SCHEDULE</code>). Trigger an immediate scan via the refresh icon at the top of the web interface, or wait for the next interval.</p>
<p><strong>The app won&rsquo;t connect.</strong> Almost always the server URL: it must be <code>https://YOUR_DOMAIN</code> (with <code>https://</code>, no path). Also check that username/password are exactly right – some apps additionally require enabling Subsonic compatibility, which is on by default in Navidrome.</p>
<p><strong>Playback stutters on large FLAC files over mobile.</strong> The bandwidth isn&rsquo;t enough for the original. Enable transcoding for the mobile player (see the tip in step 7).</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>Updates.</strong> Occasionally bump the image tag (<code>deluan/navidrome:0.63.2</code>) to the current version and <code>docker compose up -d</code>; Navidrome migrates its database at start. The rest runs through your normal <a href="/en/tutorials/keep-docker-stack-updated/">update process</a>.</li>
<li><strong>Two-part backup.</strong> Your <strong>music</strong> is the valuable, irreplaceable part – it belongs in your <a href="/en/tutorials/restic-backups/">Restic backup</a> anyway (or you have it elsewhere). The <code>data</code> folder (Navidrome&rsquo;s index, play statistics, playlists, user accounts) is small and should be backed up too; in a pinch it can also be rebuilt by a fresh scan.</li>
<li><strong>Low effort.</strong> After setup, maintenance mainly means dropping new music into the folder – the hourly scan handles the rest. As the collection grows, watch the disk space (<code>df -h</code>); music adds up fast.</li>
</ul>
]]></content:encoded></item></channel></rss>