<?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>Podcasts – Serverküche</title><link>https://serverkueche.de/en/tags/podcasts/</link><description>Podcasts – 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, 24 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/en/tags/podcasts/index.xml" rel="self" type="application/rss+xml"/><item><title>Audiobookshelf: Self-Host Audiobooks &amp; Podcasts</title><link>https://serverkueche.de/en/tutorials/audiobookshelf-audiobooks/</link><pubDate>Thu, 24 Sep 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/audiobookshelf-audiobooks/</guid><description>Set up Audiobookshelf 2.36 with Docker and Traefik: an audiobook library with chapters, podcast subscriptions, server-side listening progress and mobile apps.</description><content:encoded><![CDATA[<p>For most people, audiobooks are an MP3 collection on a hard drive – and the listening position lives
in their head. Audiobookshelf turns that into your own audiobook and podcast server: it remembers
where you stopped, continues on your phone and fetches new podcast episodes by itself.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>At the end, <strong>Audiobookshelf 2.36.0</strong> runs in Docker behind your Traefik at <code>https://YOUR_DOMAIN</code>
with a valid Let&rsquo;s Encrypt certificate. You get two libraries: one for <strong>audiobooks</strong> (with chapters,
covers and metadata from Audible) and one for <strong>podcasts</strong> that downloads new episodes
automatically. Listening progress is stored server-side in your account – you continue on your
desktop exactly where your phone left off.</p>
<p>Audiobookshelf isn&rsquo;t meant for <strong>music</strong> – <a href="/en/tutorials/navidrome-stream-music/">Navidrome</a>
is the right tool for that, and <a href="/en/tutorials/jellyfin-media-server/">Jellyfin</a> for films and
series. All three run happily side by side.</p>
<p>Audiobookshelf is pleasantly lightweight: the container uses around <strong>55 MiB RAM</strong> when idle, the
image is 469 MB. Disk space is needed almost exclusively by your audio files.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A server running Debian 13 with Docker (tested on a netcup VPS with Docker 29.6.1 and
Compose v5.3.1)</li>
<li>A <strong>running Traefik</strong> with its <code>proxy</code> network, as set up in
<a href="/en/tutorials/traefik-reverse-proxy/">Traefik as a reverse proxy</a></li>
<li>A subdomain pointing at your server – see
<a href="/en/tutorials/connect-domain-to-server/">Connecting a domain to your server</a></li>
<li>The basics of <a href="/en/tutorials/docker-compose-basics/">Docker Compose</a> and
<a href="/en/tutorials/docker-volumes-vs-bind-mounts/">bind mounts</a></li>
<li>Your audiobook files (MP3, M4B, FLAC …). If you have none yet: LibriVox offers public-domain
audiobooks in many languages.</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/audiobookshelf-audiobooks/" 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">Plenty for Audiobookshelf – the service itself is tiny, the files need the space.</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"
     data-voucher-pool="vps-1000" data-voucher-codes="[&#34;6877nc17905136544&#34;,&#34;6877nc17905136543&#34;,&#34;6877nc17905136542&#34;,&#34;6877nc17905136541&#34;,&#34;6877nc17905136540&#34;,&#34;6877nc17905133999&#34;,&#34;6877nc17905133998&#34;,&#34;6877nc17905133997&#34;,&#34;6877nc17905133996&#34;,&#34;6877nc17905133995&#34;,&#34;6877nc17905133994&#34;,&#34;6877nc17905133993&#34;,&#34;6877nc17905133992&#34;,&#34;6877nc17905133991&#34;,&#34;6877nc17905133990&#34;]">
  <p class="flex flex-wrap items-center gap-x-2 gap-y-1">
    <span>💶 <span class="font-semibold">1 month free</span> for new netcup customers:</span>
    <button type="button" data-voucher-code data-track-voucher="6877nc17905136544"
            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">6877nc17905136544</button>
    <button type="button" data-voucher-next hidden
            class="rounded border border-herb-500/40 px-2 py-0.5 text-xs text-herb-800 hover:bg-white dark:text-herb-400 dark:hover:bg-slate-800">another code</button>
  </p>
  <p class="mt-1 text-xs text-slate-500 dark:text-slate-400">
    Single use, valid for VPS 1000 G12.5.
    <a href="https://www.netcup.com/en/checkout/cart?ref=44083" rel="sponsored noopener" target="_blank"
       data-track-event="Affiliate|netcup: Gutschein einlösen|VPS 1000 G12.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><p class="mt-2 flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-herb-500/30 pt-2">
    <span>💶 <span class="font-semibold">€5 voucher</span> 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">always valid · not for domains or VPS Lite</span>
  </p>
</div></div>
</div>

<h2 id="step-by-step">Step by step</h2>
<h3 id="1-create-the-directories">1. Create the directories</h3>
<p>Audiobookshelf separates four data areas – and that separation is exactly what makes backups easy
later: <strong>config</strong> (database, accounts), <strong>metadata</strong> (covers, cache, internal backups) and your
<strong>media</strong> in their own folders.</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/audiobookshelf/<span class="o">{</span>config,metadata,audiobooks,podcasts<span class="o">}</span></span></span></code></pre></div>
</div>
<p>The image starts as <code>root</code> by default; with the <code>user: &quot;1000:1000&quot;</code> above, the process runs
under UID/GID 1000 instead. The folders therefore have to belong to
that user, otherwise Audiobookshelf can neither scan nor store podcasts:</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">chown -R 1000:1000 /opt/audiobookshelf</span></span></code></pre></div>
</div>
<h3 id="2-add-audiobooks--the-folder-structure-decides">2. Add audiobooks – the folder structure decides</h3>
<p>Audiobookshelf derives author and title <strong>from the folder structure</strong> and enriches them with the
tags inside the files. Stick to <code>Author/Title/</code> and the mapping is right from the start:</p>
<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">/opt/audiobookshelf/audiobooks/
</span></span><span class="line"><span class="cl">└── Franz Kafka/
</span></span><span class="line"><span class="cl">    └── Ein Landarzt/
</span></span><span class="line"><span class="cl">        ├── landarzt_01.mp3
</span></span><span class="line"><span class="cl">        ├── landarzt_02.mp3
</span></span><span class="line"><span class="cl">        ├── landarzt_03.mp3
</span></span><span class="line"><span class="cl">        └── landarzt_04.mp3</span></span></code></pre></div>
</div>
<p>Several files in <strong>one</strong> title folder are combined into a single audiobook with chapters – not into
four separate books. After copying, fix the ownership:</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">chown -R 1000:1000 /opt/audiobookshelf/audiobooks</span></span></code></pre></div>
</div>
<h3 id="3-write-the-compose-file">3. Write the Compose file</h3>
<p>Create <code>/opt/audiobookshelf/compose.yaml</code> and replace <code>YOUR_DOMAIN</code> with your real subdomain:</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">audiobookshelf</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">ghcr.io/advplyr/audiobookshelf:2.36.0</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">TZ</span><span class="p">:</span><span class="w"> </span><span class="l">Europe/Berlin</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">./config:/config</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./metadata:/metadata</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./audiobooks:/audiobooks</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./podcasts:/podcasts</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.abs.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.abs.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.abs.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.abs.loadbalancer.server.port=80&#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>Three details matter here:</p>
<ul>
<li><strong><code>loadbalancer.server.port=80</code></strong> – inside the container Audiobookshelf listens on port 80. The
13378 from the official example Compose is only the port you publish when running <em>without</em> a
reverse proxy. We publish <strong>no</strong> port at all: Traefik reaches the container through the <code>proxy</code>
network.</li>
<li><strong>The pinned version</strong> <code>2.36.0</code> instead of <code>latest</code> – updates then arrive when you plan them, not
in the middle of the week.</li>
<li><strong><code>user: &quot;1000:1000&quot;</code></strong> matches the ownership from step 1.</li>
</ul>
<p>Start the stack:</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"><span class="nb">cd</span> /opt/audiobookshelf <span class="o">&amp;&amp;</span> docker compose up -d</span></span></code></pre></div>
</div>
<p>Check that the container is running:</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 ps</span></span></code></pre></div>
</div>
<p>You should see <code>Up</code>, not <code>Restarting</code>:</p>
<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">NAME                              STATUS         IMAGE
</span></span><span class="line"><span class="cl">audiobookshelf-audiobookshelf-1   Up 8 seconds   ghcr.io/advplyr/audiobookshelf:2.36.0</span></span></code></pre></div>
</div>
<h3 id="4-verify-tls-before-you-click">4. Verify TLS before you click</h3>
<p>Traefik needs a few seconds for the certificate. The status endpoint tells you whether everything is
in place – it answers without a login:</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">curl https://YOUR_DOMAIN/status</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">{&#34;app&#34;:&#34;audiobookshelf&#34;,&#34;serverVersion&#34;:&#34;2.36.0&#34;,&#34;isInit&#34;:false,&#34;language&#34;:&#34;en-us&#34;,
</span></span><span class="line"><span class="cl"> &#34;authMethods&#34;:[&#34;local&#34;],&#34;ConfigPath&#34;:&#34;/config&#34;,&#34;MetadataPath&#34;:&#34;/metadata&#34;}</span></span></code></pre></div>
</div>
<p>Two things are now certain: <strong>2.36.0</strong> really is running, and <code>isInit:false</code> means the server is
still waiting for its first account. If you get a certificate error here, look at the Traefik logs
first – not at Audiobookshelf.</p>
<h3 id="5-create-the-first-account">5. Create the first account</h3>
<p>Open <code>https://YOUR_DOMAIN</code> in your browser. On the first visit Audiobookshelf asks for a username
and password for the <strong>root account</strong>, i.e. the administrator.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>No registration – and no password recovery
  </p>
  <div class="prose-kitchen text-sm">Audiobookshelf deliberately has <strong>no</strong> open registration: you add further users yourself under
<strong>Settings → Users</strong>. But there is no „forgot password&quot; for the root account either – store it in a
password manager, for example in
<a href="/en/tutorials/vaultwarden-password-manager/">Vaultwarden</a>.</div>
</div>
<p>Afterwards you&rsquo;ll notice the address jumps to <code>https://YOUR_DOMAIN/audiobookshelf/</code>. That is
intentional on the project&rsquo;s side: the web interface is built with the fixed router path
<code>/audiobookshelf</code>. There is a <code>ROUTER_BASE_PATH</code> variable, but it does not help at runtime – the path
is baked into the pre-built frontend inside the image (tested: with <code>ROUTER_BASE_PATH: &quot;&quot;</code> the
interface still loads from <code>/audiobookshelf/_nuxt/…</code>). Visiting <code>https://YOUR_DOMAIN</code> still works,
your bookmarks just carry the suffix.</p>
<h3 id="6-a-note-on-the-interface-language">6. A note on the interface language</h3>
<p>The interface follows a <strong>per-browser</strong> setting, not a per-account one: Audiobookshelf stores it
locally and does not save it on the user. You pick it under your username in the top right corner
(<strong>Language</strong>), and you have to set it again on every new device.</p>
<h3 id="7-create-the-audiobook-library">7. Create the audiobook library</h3>
<p>Under <strong>Settings → Libraries</strong> you create the first library:</p>
<p><figure class="my-6"><img src="/en/tutorials/audiobookshelf-audiobooks/bibliothek-anlegen_hu_3fdc04e299a824b7.webp" srcset="/en/tutorials/audiobookshelf-audiobooks/bibliothek-anlegen_hu_b736ee24ffcdd8ba.webp 480w, /en/tutorials/audiobookshelf-audiobooks/bibliothek-anlegen_hu_3fdc04e299a824b7.webp 768w, /en/tutorials/audiobookshelf-audiobooks/bibliothek-anlegen_hu_3f067c821dc76346.webp 1200w, /en/tutorials/audiobookshelf-audiobooks/bibliothek-anlegen_hu_c4fe4d34ae62d4e7.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/audiobookshelf-audiobooks/bibliothek-anlegen_hu_5192342ff9947008.webp"
    alt="The „New Library&quot; dialog in Audiobookshelf with media type Books, a library name, Audible as the metadata provider and the /audiobooks folder" title="New Library: media type, name, metadata provider and folder"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">New Library: media type, name, metadata provider and folder</figcaption></figure></p>
<ul>
<li><strong>Media Type:</strong> <code>Books</code></li>
<li><strong>Library Name:</strong> e.g. <code>Audiobooks</code></li>
<li><strong>Metadata Provider:</strong> pick the Audible catalogue for your language – <code>Audible.com</code> for English
titles gives noticeably better matches than the default <code>Google Books</code>. iTunes, FantLab.ru and the
other Audible country catalogues are available too.</li>
<li><strong>Folders:</strong> enter <code>/audiobooks</code> and confirm with Enter. That is the path <strong>inside the container</strong> –
thanks to the bind mount it points at <code>/opt/audiobookshelf/audiobooks</code>.</li>
</ul>
<p>Then click <strong>Create</strong>.</p>
<h3 id="8-trigger-the-first-scan-yourself">8. Trigger the first scan yourself</h3>
<p>This is where most people stumble: the library stays empty at first, and the interface says so.</p>
<p>The <strong>first scan does not start on its own</strong> – not even after minutes (measured). In the library view,
use the scan action offered next to that notice. With four files and 14 MB the scan finished in under
four seconds, after which the audiobook appears with its cover:</p>
<p><figure class="my-6"><img src="/en/tutorials/audiobookshelf-audiobooks/bibliothek_hu_bfb20f7192b6bd29.webp" srcset="/en/tutorials/audiobookshelf-audiobooks/bibliothek_hu_996960177c871ae8.webp 480w, /en/tutorials/audiobookshelf-audiobooks/bibliothek_hu_bfb20f7192b6bd29.webp 768w, /en/tutorials/audiobookshelf-audiobooks/bibliothek_hu_404f18c3b0dd3ef7.webp 1200w, /en/tutorials/audiobookshelf-audiobooks/bibliothek_hu_f75a5192d42ebd80.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/audiobookshelf-audiobooks/bibliothek_hu_f8830bb7745c8958.webp"
    alt="The Audiobookshelf library showing the imported audiobook after the scan, with its cover under recently added" title="After the scan the audiobook appears with its cover"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">After the scan the audiobook appears with its cover</figcaption></figure></p>
<p>From now on Audiobookshelf watches the folder itself: newly copied files are picked up, and a manual
scan is only needed when creating the library.</p>
<h3 id="9-listening--chapters-speed-sleep-timer">9. Listening – chapters, speed, sleep timer</h3>
<p>Clicking the cover opens the detail page. The four MP3s have become one audiobook with <strong>four
chapters</strong>; duration and size are shown at the top:</p>
<p><figure class="my-6"><img src="/en/tutorials/audiobookshelf-audiobooks/player_hu_f9d6f85f0afedd71.webp" srcset="/en/tutorials/audiobookshelf-audiobooks/player_hu_44b3ca3f6ed97602.webp 480w, /en/tutorials/audiobookshelf-audiobooks/player_hu_f9d6f85f0afedd71.webp 768w, /en/tutorials/audiobookshelf-audiobooks/player_hu_afe9b16338710812.webp 1200w, /en/tutorials/audiobookshelf-audiobooks/player_hu_6cbfd1973128ccf2.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/audiobookshelf-audiobooks/player_hu_f4c7304d69342a9f.webp"
    alt="The audiobook detail page with playback running, chapter and file list, and the player at the bottom" title="Detail page with chapters and the running player"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Detail page with chapters and the running player</figcaption></figure></p>
<p>The player at the bottom stays put while you navigate. It offers playback speed (<code>1.0x</code>), jump
marks, bookmarks, the chapter list and a <strong>sleep timer</strong>. The progress – <code>0:06 / 28:52</code> in the
screenshot – is stored server-side in your account, not in the browser. That is precisely why you
self-host this thing.</p>
<h3 id="10-subscribe-to-podcasts">10. Subscribe to podcasts</h3>
<p>Podcasts need their <strong>own library</strong>, because Audiobookshelf treats them differently: episodes, feeds,
automatic downloads. So go to <strong>Settings → Libraries → Add Library</strong> again, this time with:</p>
<ul>
<li><strong>Media Type:</strong> <code>Podcasts</code></li>
<li><strong>Name:</strong> e.g. <code>Podcasts</code></li>
<li><strong>Metadata Provider:</strong> <code>iTunes</code></li>
<li><strong>Folder:</strong> <code>/podcasts</code></li>
</ul>
<p>In the new library, click <strong>Add</strong>. The input field takes either a search term – then the <strong>server</strong>
queries the iTunes catalogue – or the feed URL directly:</p>
<p><figure class="my-6"><img src="/en/tutorials/audiobookshelf-audiobooks/podcast-suche_hu_3dcaf9610b74e5a8.webp" srcset="/en/tutorials/audiobookshelf-audiobooks/podcast-suche_hu_b1cf4469394474cf.webp 480w, /en/tutorials/audiobookshelf-audiobooks/podcast-suche_hu_3dcaf9610b74e5a8.webp 768w, /en/tutorials/audiobookshelf-audiobooks/podcast-suche_hu_48b47aaf02cc487e.webp 1200w, /en/tutorials/audiobookshelf-audiobooks/podcast-suche_hu_1767d60f69176105.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/audiobookshelf-audiobooks/podcast-suche_hu_a71aba8995ace0f8.webp"
    alt="The podcast search in Audiobookshelf with two results for a search term, including the episode count" title="Podcast search: results from the iTunes catalogue with episode counts"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Podcast search: results from the iTunes catalogue with episode counts</figcaption></figure></p>
<p>When subscribing you decide whether <strong>new episodes are downloaded automatically</strong> and how many
Audiobookshelf keeps. Keep disk space in mind: a weekly podcast with 60-minute episodes costs roughly
30 MB per episode at 64 kbps and 55 MB at 128 kbps – so about
1.5 to 3 GB per year.</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>Feed instead of search
  </p>
  <div class="prose-kitchen text-sm">The search queries the iTunes catalogue. If it cannot find a podcast because it is not listed there,
add it directly via its RSS address – the same input field accepts both.</div>
</div>
<h3 id="11-add-more-users">11. Add more users</h3>
<p>Listening progress belongs to an account – so create separate users for your partner or kids instead
of sharing the root account. That happens under <strong>Settings → Users → Add User</strong>.</p>
<p>There are three account types: <code>root</code> (only once, the first account), <code>admin</code> (may change settings
and libraries) and <code>user</code> for the normal case. A freshly created <code>user</code> account gets these
permissions:</p>
<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">download: true       – may download titles (for offline listening in the app)
</span></span><span class="line"><span class="cl">update: false        – may not change metadata
</span></span><span class="line"><span class="cl">delete: false        – may not delete anything
</span></span><span class="line"><span class="cl">upload: false        – may not upload files
</span></span><span class="line"><span class="cl">accessAllLibraries:  true    – sees ALL libraries
</span></span><span class="line"><span class="cl">accessExplicitContent: false – titles flagged explicit stay hidden</span></span></code></pre></div>
</div>
<p>The second-to-last line is the important one: by default a new user sees <strong>all</strong> libraries. If the
kids should not browse the grown-up audiobooks, turn <code>accessAllLibraries</code> off in the user dialog and
pick the allowed libraries individually.</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>Tip
  </p>
  <div class="prose-kitchen text-sm">Under <strong>Settings → Library Statistics</strong> and your own statistics you can see how many hours were
listened to and what runs most often – nice to have, but also practical for spotting unused podcast
subscriptions that only eat disk space.</div>
</div>
<h3 id="12-apps-for-your-phone">12. Apps for your phone</h3>
<p>Everyday use happens on the phone. There is an official Audiobookshelf app for <strong>Android</strong> (Play
Store and F-Droid) and for <strong>iOS</strong>. On first launch you enter:</p>
<ul>
<li><strong>Server address:</strong> <code>https://YOUR_DOMAIN</code> – with <code>https://</code>, without a path</li>
<li><strong>Username and password</strong> of your account</li>
</ul>
<p>The app then downloads titles for offline listening and reports progress back to the server. On iOS
there are also alternatives such as Plappa or ShelfPlayer that use the same API.</p>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong>The library stays empty after you create it.</strong> The first scan does not run automatically – that is
not a bug but how Audiobookshelf behaves. Trigger the scan in the library view. If it stays empty
afterwards, check with <code>docker compose exec audiobookshelf ls -R /audiobooks</code> whether the
container sees the files at all, and with <code>ls -ln /opt/audiobookshelf/audiobooks</code> that everything is
owned by UID 1000.</p>
<p><strong>Four MP3 files become four audiobooks instead of four chapters.</strong> The files sit directly in the
author folder instead of a shared title folder. Audiobookshelf groups by <code>Author/Title/</code> – move the
files into a subfolder named after the book and scan again.</p>
<p><strong>Traefik answers with 404 even though the container is running.</strong> Usually
<code>traefik.http.services.abs.loadbalancer.server.port=80</code> is missing. Inside the container
Audiobookshelf listens on <strong>80</strong>; without that line Traefik guesses and misses. Also check that the
container really is attached to the <code>proxy</code> network.</p>
<p><strong>The address jumps to <code>/audiobookshelf/</code>.</strong> That is normal: the frontend ships with this fixed
router path, and <code>ROUTER_BASE_PATH</code> changes nothing at runtime because the path is baked into the
image. <code>https://YOUR_DOMAIN</code> remains a valid entry point.</p>
<p><strong>After switching devices the language is back to English.</strong> The language choice lives locally in the
browser, not on the account. Set it once per device via your username → <code>Language</code>.</p>
<p><strong>The podcast is not found.</strong> The search queries the iTunes catalogue; a typo or a missing entry
there leads to „no search results&quot;. Use the podcast&rsquo;s RSS URL instead – the same field accepts both.</p>

</div>
<p class="mt-3 text-sm text-slate-500 dark:text-slate-400">
  Your problem is not listed?
  <a href="/en/errors/" class="font-medium text-paprika-700 hover:underline dark:text-paprika-400">Search all error messages →</a>
</p>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<p><strong>Updates.</strong> Audiobookshelf releases often, roughly a new minor version per month. Because the
version is pinned, you update deliberately: raise the tag in <code>compose.yaml</code>, then</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"><span class="nb">cd</span> /opt/audiobookshelf <span class="o">&amp;&amp;</span> docker compose pull <span class="o">&amp;&amp;</span> docker compose up -d</span></span></code></pre></div>
</div>
<p>Before jumping across several versions, read the release notes – and take a fresh backup. How to do
this systematically is described in
<a href="/en/tutorials/keep-docker-stack-updated/">Keeping your Docker stack up to date</a>.</p>
<p><strong>The built-in backup – switch it on first.</strong> Audiobookshelf can write archives itself, but it does
<strong>not</strong> do so out of the box: under <strong>Settings → Backups</strong> the automatic backup toggle is <strong>off</strong> by
default.</p>
<p><figure class="my-6"><img src="/en/tutorials/audiobookshelf-audiobooks/sicherungen_hu_66b37ddc2ac7482c.webp" srcset="/en/tutorials/audiobookshelf-audiobooks/sicherungen_hu_261a7ff779d65cba.webp 480w, /en/tutorials/audiobookshelf-audiobooks/sicherungen_hu_66b37ddc2ac7482c.webp 768w, /en/tutorials/audiobookshelf-audiobooks/sicherungen_hu_8e734ccc11930356.webp 1200w, /en/tutorials/audiobookshelf-audiobooks/sicherungen_hu_92e299802afb0aab.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/audiobookshelf-audiobooks/sicherungen_hu_3de52265fef9d3fd.webp"
    alt="The Backups settings page in Audiobookshelf with automatic backup disabled, the backup path /metadata/backups, retention 2 and a maximum size of 1 GB" title="Backups: the automatic backup is off by default"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Backups: the automatic backup is off by default</figcaption></figure></p>
<p>Switch it on and check the two limits below it, because both are set tight:</p>
<ul>
<li><strong>Number of backups to keep: 2</strong> – older ones are deleted. For „I only notice a problem two weeks
later&quot; that is too few; 7 to 14 is more realistic.</li>
<li><strong>Maximum backup size: 1 GB</strong> – if the archive grows larger, the backup aborts. With many covers in
<code>/metadata</code> that can happen; <code>0</code> means „no limit&quot;.</li>
</ul>
<p>The archives end up in <code>/metadata/backups</code>, in our case
<code>/opt/audiobookshelf/metadata/backups</code>. They contain users, listening progress, library item details,
server settings and the images from <code>/metadata/items</code> and <code>/metadata/authors</code>. The interface states it
clearly itself: <strong>files from your media folders are not included.</strong></p>
<p>Restoring works on the same page via the upload option – worth knowing, because it reduces a move to
a new server to two steps: upload the archive, copy the media.</p>
<p><strong>Real backups.</strong> That gives you a clear split:</p>
<ul>
<li><code>config/</code> and <code>metadata/</code> are small (480 KB and 112 KB here) and belong in a <strong>daily</strong> backup –
that is where the actual work lives: accounts, progress, metadata.</li>
<li><code>audiobooks/</code> and <code>podcasts/</code> are large and rarely change. They need a backup too, but on a
different schedule – podcast episodes can even be classed as „re-downloadable any time&quot;.</li>
</ul>
<p><a href="/en/tutorials/restic-backups/">Restic</a> handles both reliably. Once a quarter, verify with a real
restore that the backup actually comes back.</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>Trigger a scan via the API
  </p>
  <div class="prose-kitchen text-sm"><p>If you push audiobooks onto the server by script or Syncthing, you do not need the web interface:
Audiobookshelf has an HTTP API. Create a token under <strong>Settings → API Keys</strong>, then this call starts
the scan of a library:</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">curl -X POST https://YOUR_DOMAIN/api/libraries/YOUR_LIBRARY_ID/scan <span class="se">\
</span></span></span><span class="line"><span class="cl">  -H <span class="s2">&#34;Authorization: Bearer YOUR_TOKEN&#34;</span></span></span></code></pre></div>
</div>
<p><code>GET /api/libraries</code> returns your library IDs with the same header. Handy for a cron job after the
nightly file sync – how to monitor such jobs is covered in
<a href="/en/tutorials/healthchecks-monitor-jobs/">Healthchecks</a>.</p>
</div>
</div>
<p><strong>Keep an eye on disk space.</strong> Audio files and automatically downloaded episodes are the only real
space eaters:</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">du -sh /opt/audiobookshelf/*</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">14M     /opt/audiobookshelf/audiobooks
</span></span><span class="line"><span class="cl">480K    /opt/audiobookshelf/config
</span></span><span class="line"><span class="cl">112K    /opt/audiobookshelf/metadata
</span></span><span class="line"><span class="cl">4.0K    /opt/audiobookshelf/podcasts</span></span></code></pre></div>
</div>
<p>If it grows beyond your disk, additional block storage for the media folders is the cheaper answer
than a bigger server – the rest of Audiobookshelf stays tiny.</p>
]]></content:encoded></item></channel></rss>