Audiobookshelf

Self-hosted audiobook and podcast server with mobile apps and progress sync.

MediabeginnerProduction-ready defaults1 services

The stack

Generated output

docker-compose.yml
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:2.35.1@sha256:1eef6716183c52abafe5405e7d6be8390248ecd59c7488c44af871757ac8fc4d
    restart: unless-stopped
    environment:
      PORT: "13378"
      TZ: ${TZ}
    volumes:
      - audiobookshelf-config:/config
      - audiobookshelf-metadata:/metadata
      - ${AUDIOBOOKS_PATH}:/audiobooks
      - ${PODCASTS_PATH}:/podcasts
volumes:
  audiobookshelf-config: {}
  audiobookshelf-metadata: {}

Replace audiobooks.example.com with your domain. Generate secrets below.

Environment

.env with generated secrets

.env
# Host directory that holds your audiobook files. Mounted read-write at /audiobooks and scanned as a Books library.
# Host directory for podcasts. Mounted at /podcasts and scanned as a Podcasts library; auto-downloaded episodes land here.
# Timezone for scheduled podcast downloads, backups, and log timestamps (IANA tz name).

Secrets are generated in your browser via crypto.getRandomValues. Nothing is sent anywhere.

Server-rendered .env template
# Host directory that holds your audiobook files. Mounted read-write at /audiobooks and scanned as a Books library.
AUDIOBOOKS_PATH=./audiobooks

# Host directory for podcasts. Mounted at /podcasts and scanned as a Podcasts library; auto-downloaded episodes land here.
PODCASTS_PATH=./podcasts

# Timezone for scheduled podcast downloads, backups, and log timestamps (IANA tz name).
TZ=UTC

About

What is Audiobookshelf?

Audiobookshelf is a self-hosted server for your audiobook and podcast libraries. It indexes folders of audio files, pulls in cover art and metadata, and streams everything to a polished web player and to native iOS and Android apps — so your listening position follows you from the car to your headphones to the browser without ever re-finding your place. Progress, bookmarks, and playback speed sync continuously across every device against a single account, and the server keeps per-user listening history and stats. It is genuinely multi-user: create accounts for a household, scope each one to specific libraries, and hand out permissions without sharing one login. Beyond audiobooks it treats podcasts as first-class content — subscribe to feeds, auto-download new episodes on a schedule, and keep them in the same player. There is light ebook support too, with an in-browser reader for EPUB and PDF. This stack runs the official Audiobookshelf image as a single container. Two named volumes hold the application's own data — config holds the SQLite database, users, and settings, while metadata holds cached covers, downloads, and backups — and your actual media lives on host directories you point at through environment variables, exactly like Immich's upload-location pattern, so your existing audiobook and podcast folders stay where they are. The compose file binds nothing to the host: the reverse proxy at audiobooks.example.com terminates TLS and forwards to the container on port 13378, which is also where the real-time progress-sync WebSocket runs.

Requirements

Before you start

  • 1 GB RAM is comfortable. Audiobookshelf itself is light, but scanning large libraries and embedding metadata is CPU- and I/O-heavy.
  • Docker 24+ and Docker Compose v2.
  • Storage for your media, plus a persistent disk for the config and metadata volumes — the config volume is your user database and listening progress.
  • Your audiobook and podcast files in host directories that are readable by the container. Audiobookshelf scans the paths mounted at /audiobooks and /podcasts.

Deploy

How to deploy

  1. Point `AUDIOBOOKS_PATH` and `PODCASTS_PATH` in `.env` at the host folders that already hold your media (they default to `./audiobooks` and `./podcasts`).
  2. Optionally set `TZ` so scheduled podcast downloads and backups run on your local clock.
  3. Start the stack: `docker compose up -d`.
  4. Open `https://audiobooks.example.com` and create the root (admin) account in the first-run setup — there is no default password; the first account you make is the admin.
  5. Add a library: choose the Books type and point it at `/audiobooks`, then add a second Podcasts library pointed at `/podcasts`. Audiobookshelf scans and matches metadata.
  6. Install the Audiobookshelf app (iOS or Android), set the server address to `https://audiobooks.example.com`, and log in.

Errors

Common errors & fixes

The reverse proxy returns 502 Bad Gateway and the web UI never loads.

The proxy forwards to the container on port 13378, which is what `PORT` is set to in this compose. The upstream image default is 80, which this stack deliberately overrides — if you change `PORT`, the `webPort` the proxy targets must change to match. Confirm both are 13378.

A library shows no items after you add it.

The mounted path is wrong or unreadable. `AUDIOBOOKS_PATH`/`PODCASTS_PATH` must point at the host folder that actually contains your files, and those files must be readable by the container. Audiobookshelf expects roughly one folder per book; loose files dropped in the library root may not be matched.

Playback position does not sync between the web player and the mobile app.

Audiobookshelf syncs progress over a WebSocket (Socket.IO) on the same host and port as the UI. Make sure the reverse proxy forwards WebSocket upgrades — Caddy and Traefik do this by default; a custom proxy that strips the `Upgrade`/`Connection` headers breaks sync.

After recreating the container, all users, libraries, and progress are gone.

The `audiobookshelf-config` volume was not persisted. The SQLite database, users, and progress live in `/config`; keep that named volume (and back it up) across redeploys. Re-pulling the image is safe — deleting the volume is not.

Limitations

Honest limitations

  • No server-side transcoding. Unlike Plex or Jellyfin, Audiobookshelf streams the original files and relies on the client to decode them — fine for common formats (MP3, M4B, AAC, FLAC, Opus), but unusual codecs depend on what the player supports.
  • The initial scan of a large collection can take a long time and is I/O-intensive, especially while matching metadata and reading chapters; expect the first index to run for a while before everything appears.
  • Ebook support is secondary to audio. There is an in-browser EPUB/PDF reader, but this is not a Calibre-class ebook manager.
  • Single instance only — no built-in clustering or high availability. Back up the config and metadata volumes to protect against host loss.

FAQ

Frequently asked

Does Audiobookshelf transcode like Plex or Jellyfin?+

No. It serves your original audio files and the apps play them directly. That keeps the server light and avoids a transcoding farm, but it means playback of an unusual codec depends on client support rather than the server converting on the fly.

Which apps can I use?+

The official Audiobookshelf app for iOS and Android connects directly to your server, downloads titles for offline listening, and syncs progress back. There is also a healthy ecosystem of third-party clients (for example Plappa, Prologue, and ShelfPlayer on iOS) that speak the same API.

Can several people use one server with separate progress?+

Yes. Audiobookshelf is multi-user: each account has its own listening progress, bookmarks, and stats, and you can scope accounts to specific libraries and set per-user permissions. The first account you create is the admin.

Does it handle podcasts as well as audiobooks?+

Podcasts are first-class. Add a Podcasts library, search and subscribe to feeds, and let the server auto-download new episodes on a schedule. They share the same player, progress sync, and apps as your audiobooks.

How do I back it up?+

Two pieces: the `audiobookshelf-config` volume (database, users, progress) and the `audiobookshelf-metadata` volume (covers, downloads, and Audiobookshelf's own scheduled backups). Your media is your own files on disk and is backed up separately.

Related

Related stacks