tagIntroduction

Audiobookshelf is an open-source self-hosted media server for your audiobooks and podcasts.

Features include...

  • Companion android and iOS app w/ offline listening (in beta)
  • Multi-user support w/ custom permissions
  • Keeps progress per user and syncs across devices
  • Lookup and apply metadata and cover art from several providers
  • Audiobook chapter editor w/ chapter lookup
  • Audiobook tools: Embed metadata in audio files & merge multiple audio files to a single m4b
  • Search and add podcasts to download episodes w/ auto-download
  • Open RSS feeds for audiobooks and podcast episodes
  • Backups with automated backup scheduling
  • Basic ebook support and ereader (epub, pdf, cbr, cbz) + send to device (i.e. Kindle)
  • And much more...

Join our Discord server.

If you are interested in integrating with Audiobookshelf, visit the API documentation.

The source for this documentation can be found at the Audiobookshelf GitHub repository. Contributions to this documentation can be made through a pull request.

tagDocker Compose

services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    ports:
      - 13378:80
    volumes:
      - </path/to/audiobooks>:/audiobooks
      - </path/to/podcasts>:/podcasts
      - </path/to/config>:/config
      - </path/to/metadata>:/metadata
    environment:
      - TZ=America/Toronto
  • Remember to change the path to your actual directory and remove the <> symbols
  • Volume mappings should all be separate directories that are not contained in eachother

Volume mappings

  • /config will contain the database (users/books/libraries/settings). Beginning with 2.3.x, this needs to be on the same machine you are running ABS on.
  • /metadata will contain cache, streams, covers, downloads, backups and logs
  • Map any other directories you want to use for your book and podcast collections (ebooks supported)

Still confused about Docker? Check out this FAQ

💡 Prefer the CLI? This is our docker run command. YMMV

docker pull ghcr.io/advplyr/audiobookshelf

docker run -d \
 -p 13378:80 \
 -v </path/to/config>:/config \
 -v </path/to/metadata>:/metadata \
 -v </path/to/audiobooks>:/audiobooks \
 -v </path/to/podcasts>:/podcasts \
 --name audiobookshelf \
 -e TZ="America/Toronto" \
 ghcr.io/advplyr/audiobookshelf

⚠️ Windows users will need to remove the \ and run this as a single line

tagLinux (Debian, Ubuntu, …)

Only for amd64 architecture.

For Debian based systems, you can activate the official Audiobookshelf repository and install the Debian package.

Installation

Activate the repository:

sudo apt install gnupg curl
wget -O- https://advplyr.github.io/audiobookshelf-ppa/KEY.gpg | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/adb-archive-keyring.gpg
sudo curl -s -o /etc/apt/sources.list.d/audiobookshelf.list https://advplyr.github.io/audiobookshelf-ppa/audiobookshelf.list

Install Audiobookshelf:

sudo apt update
sudo apt install audiobookshelf

Configuration

The Audiobookshelf service will use the config file localted at /etc/default/audiobookshelf. The default configuration is as follows:

METADATA_PATH=/usr/share/audiobookshelf/metadata
CONFIG_PATH=/usr/share/audiobookshelf/config
FFMPEG_PATH=/usr/lib/audiobookshelf-ffmpeg/ffmpeg
FFPROBE_PATH=/usr/lib/audiobookshelf-ffmpeg/ffprobe
TONE_PATH=/usr/lib/audiobookshelf-ffmpeg/tone
PORT=13378

If you update the configuration, restart the service by running:

sudo systemctl restart audiobookshelf.service

tagLinux (RHEL, CentOS, …)

  • This installation method is still in testing.
  • Only for amd64 architecture.
  • Supported operating systems are all Red Hat and CentOS Stream 8/9 variants.

Installation

To activate the repository, run:

dnf install -y "https://github.com/lkiesow/audiobookshelf-rpm/raw/el$(rpm -E %rhel)/audiobookshelf-repository-1-1.el$(rpm -E %rhel).noarch.rpm"

You can now install Audiobookshelf. All dependencies will be installed automatically:

dnf install audiobookshelf

Configuration

You can configure Audiobookshelf in /etc/default/audiobookshelf. Here you can add the same configuration options you would pass to the Docker container.

METADATA_PATH=/var/lib/audiobookshelf/metadata
CONFIG_PATH=/var/lib/audiobookshelf/config
PORT=13378
HOST=127.0.0.1

By default, Audiobookshelf will listen to localhost only. This should be sufficient if you install a reverse proxy (you should!). If you want to listen to all network interfaces, set HOST=0.0.0.0 instead.

Start Audiobookshelf

To run Audiobookshelf and ensure it will be started automatically after a reboot, run:

systemctl start audiobookshelf.service
systemctl enable audiobookshelf.service

To check the current status of the service, run:

systemctl status audiobookshelf.service

tagLinux (NixOS)

Installation

Imperative installation:

nix-env -iA audiobookshelf

Declarative installation:

environment.systemPackages = with pkgs; [
  audiobookshelf
];

Configuration

You can configure Audiobookshelf using the parameters to the executable. It supports the same configuration options you would pass to the Docker container, the options below are the defaults if the option is missing.

audiobookshelf --metadata "$(pwd)/metadata" \
  --config "$(pwd)/config" \
  --port 8000 \
  --host 0.0.0.0

If you use a reverse proxy (you should!) listing on localhost only would be enough. In this case set --host 127.0.0.1 instead.

Start Audiobookshelf

You can create a simple systemd service in your configuration.nix to automatically start audiobookshelf:

services.audiobookshelf {
  enable = true;
  port = 8234;
};

For further options, see the NixOS options page.

To configure a reverse nginx proxy, add the following:

services.nginx = {
  enable = true;
  virtualHosts."your.hostname.org" = {
    locations."/" = {
      proxyPass = "http://localhost:8234/";
    };
  };
};

To check the current status of the service, run:

systemctl status audiobookshelf.service

tagReverse Proxy

See Github readme for user-contributed reverse proxy configs

Please join the discord server before reporting an issue with your reverse proxy setup on Github.

tagDeploy on Easypanel

Deploying audiobookshelf on Easypanel

Easypanel it's a modern server control panel. You can use it to deploy audiobookshelf on your own server.

Deploy to Easypanel

Instructions

  1. Create a VM that runs Ubuntu on your cloud provider.
  2. Install Easypanel using the instructions from the website.
  3. Create a new project.
  4. Install audiobookshelf using the dedicated template.

tagPodman

Quadlet Container (Requires Podman version 4.4 or above)

# audiobookshelf.container
[Container]
ContainerName=audiobookshelf
Image=ghcr.io/advplyr/audiobookshelf:latest
AutoUpdate=registry
NoNewPrivileges=true
PublishPort=13378:80
Volume=</path/to/audiobooks>:/audiobooks
Volume=</path/to/books>:/books
Volume=</path/to/podcasts>:/podcasts
Volume=</path/to/config>:/config
Volume=</path/to/metadata>:/metadata

[Service]
Restart=always

[Install]
WantedBy=default.target
  • Remember to change the path to your actual directory and remove the <> symbols
  • Volume mappings should all be separate directories that are not contained in each other
  • If SELinux is enabled on your host, you may need to run the following command to allow the container to access the directories you are mapping to it:
    sudo chcon -R -t svirt_sandbox_file_t /path/to/directory

Volume mappings

  • /config will contain the database (users/books/libraries/settings). Beginning with 2.3.x, this needs to be on the same machine you are running ABS on.
  • /metadata will contain cache, streams, covers, downloads, backups and logs
  • Map any other directories you want to use for your book and podcast collections (ebooks supported)

Still confused about containers? Check out this FAQ (It is about Docker, but the concept is the same)

💡 Prefer the CLI? This is our podman run command. YMMV

podman pull ghcr.io/advplyr/audiobookshelf

podman run -d \
 -p 13378:80 \
 -v </path/to/config>:/config \
 -v </path/to/metadata>:/metadata \
 -v </path/to/audiobooks>:/audiobooks \
 -v </path/to/books>:/books \
 -v </path/to/podcasts>:/podcasts \
 --name audiobookshelf \
 -e TZ="America/Toronto" \
 ghcr.io/advplyr/audiobookshelf

tagKubernetes

Audiobookshelf Deployment in Kubernetes

Prerequisites

  1. Kubernetes Cluster Ensure you have a Kubernetes cluster running. This deployment assumes you're using nginx as the ingress controller.

  2. Ingress Controller (NGINX) Make sure NGINX ingress controller is installed and configured on your cluster. If you don't have it installed yet, you can follow the official NGINX ingress controller installation guide.

  3. Cluster Issuer for Let's Encrypt You need a ClusterIssuer to automatically manage TLS certificates using Let's Encrypt. Below is an example configuration to create a ClusterIssuer:

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-production
    spec:
      acme:
        server: https://acme-v02.api.letsencrypt.org/directory
        email: your-email@example.com  # Replace with your email
        privateKeySecretRef:
          name: letsencrypt-production-key
        solvers:
        - http01:
            ingress:
              class: nginx
    
    
  • Replace your-email@example.com with your own email address.
  • This will use HTTP-01 challenge for certificate issuance, with NGINX managing the ingress.

Apply this YAML to your cluster using:

kubectl apply -f cluster-issuer.yaml
  1. Subdomain Setup (Optional) If you want to use a subdomain, set up your DNS records to point to your Kubernetes cluster. In this case, I am using OVH as my DNS provider. Create an A record for your subdomain pointing to your cluster’s IP address.

Create Namespace for Audiobookshelf

First, create a dedicated namespace for Audiobookshelf:

apiVersion: v1
kind: Namespace
metadata:
  name: audiobookshelf-ns

Apply the namespace with:

kubectl apply -f namespace.yaml

Audiobookshelf Kubernetes Deployment

1. Audiobookshelf Service

Defines a service that exposes the Audiobookshelf application within the cluster:

apiVersion: v1
kind: Service
metadata:
  name: audiobookshelf
  namespace: audiobookshelf-ns
spec:
  selector:
    app: audiobookshelf  # Matches the label from the Deployment
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP  # Exposes the service only inside the cluster

2. Audiobookshelf Ingress

Configures access to the Audiobookshelf service via a domain name and sets up TLS encryption:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: audiobookshelf-ingress
  namespace: audiobookshelf-ns
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-production  # Refers to the Let's Encrypt ClusterIssuer
    acme.cert-manager.io/http01-ingress-class: public  # Specifies the ingress class
    nginx.ingress.kubernetes.io/rewrite-target: /  # Rewrites the URL to the service
    nginx.ingress.kubernetes.io/proxy-body-size: 2048m  # Sets the maximum allowed request body size
spec:
  rules:
  - host: audiobooks.example.com  # Replace with your domain
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: audiobookshelf  # The service to route traffic to
            port:
              number: 80
  tls:
  - hosts:
    - audiobooks.example.com  # Replace with your domain
    secretName: audiobookshelf-tls  # Secret created by Cert-Manager

3. Audiobookshelf Deployment

Deploys the Audiobookshelf application with volume mounts for storing audiobooks, podcasts, and configuration files:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: audiobookshelf
  namespace: audiobookshelf-ns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: audiobookshelf  # Matches the Service selector
  template:
    metadata:
      labels:
        app: audiobookshelf  # Matches the Deployment selector
    spec:
      containers:
      - name: audiobookshelf
        image: ghcr.io/advplyr/audiobookshelf:latest  # Audiobookshelf container image
        ports:
        - containerPort: 80  # Exposes port 80 for the application
        volumeMounts:
        - name: audiobooks-volume
          mountPath: /audiobooks  # Mounts the audiobooks directory inside the container
        - name: podcasts-volume
          mountPath: /podcasts  # Mounts the podcasts directory inside the container
        - name: config-volume
          mountPath: /config  # Mounts the configuration directory inside the container
        - name: metadata-volume
          mountPath: /metadata  # Mounts the metadata directory inside the container
      volumes:
      - name: audiobooks-volume
        hostPath:
          path: /YOUR_PATH/audiobooks/  # Path on the host for audiobooks
      - name: podcasts-volume
        hostPath:
          path: /YOUR_PATH//podcasts  # Path on the host for podcasts
      - name: config-volume
        hostPath:
          path: /YOUR_PATH//audiobookshelf  # Path on the host for configuration files
      - name: metadata-volume
        hostPath:
          path: /YOUR_PATH/metadata  # Path on the host for metadata

Apply the full manifest:

kubectl apply -f audiobookshelf-manifest.yaml

Verify that the services, ingress, and deployment are running:

kubectl get all -n audiobookshelf-ns
kubectl describe ingress audiobookshelf-ingress -n audiobookshelf-ns

tagDocker

To upgrade the server to the newest version, you just need to pull the new docker image and restart the container. If you are using Portainer or Docker Desktop, you can just update the stack and pull the new image. If you are using a pinned version number, you will need to update that version number.

Still confused about Docker? Check out this FAQ

tagDocker Compose

If you used docker compose, you just need to make sure the tag is either the version you want or latest if you want the newest release. If you want to run a specific release, such as older version, change the tag to the desired version number.

Then, you can just run the following commands.

docker compose pull
docker compose down
docker compose up --detach

Still confused about Docker? Check out this FAQ

tagPodman

If AutoUpdate policy is set to registry, you can just execute the following command:

podman auto-update

Otherwise, you can manually update the container by pulling the new image and replacing the old one.

For rootless containers: (Containers not running as root)

To pull the new image:

podman pull ghcr.io/advplyr/audiobookshelf

To start the container with the new image:

systemctl --user restart audiobookshelf

For rootful containers: (Containers running as root)

To pull the new image:

sudo podman pull ghcr.io/advplyr/audiobookshelf

To start the container with the new image:

sudo systemctl restart audiobookshelf

If you are running the container with the podman run command, you can remove the old container and start it again with the new image:

podman stop audiobookshelf
podman rm audiobookshelf
podman run -d \
  -p 13378:80 \
  -v </path/to/config>:/config \
  -v </path/to/metadata>:/metadata \
  -v </path/to/audiobooks>:/audiobooks \
  -v </path/to/books>:/books \
  -v </path/to/podcasts>:/podcasts \
  --name audiobookshelf \
  -e TZ="America/Toronto" \
  ghcr.io/advplyr/audiobookshelf

tagConfiguration

Audiobookshelf is configured via environment variables. You can pass them to your Docker container using -e VARIABLE=VALUE or set them in /etc/default/audiobookshelf if you install audiobookshelf via packages.

Here is a list of all available options:

Filesystem

  • CONFIG_PATH (default: ./config)
    • Path to the config directory.
    • It will contain the database (users/books/libraries/settings).
  • METADATA_PATH (default: ./metadata)
    • Path to the metadata directory.
    • It will contain cache, streams, covers, downloads, backups and logs.

External Tools

  • FFMPEG_PATH (default: ffmpeg)
    • Path to the ffmpeg binary.
    • If no path is set, Audiobookshelf will assume the binary to exist in the system path.
  • FFPROBE_PATH (default: ffprobe)
    • Path to the ffprobe binary.
    • If no path is set, Audiobookshelf will assume the binary to exist in the system path.
  • TONE_PATH (default: tone)
    • Path to the tone binary.
    • If no path is set, Audiobookshelf will assume the binary to exist in the system path.

Network

  • HOST
    • The host Audiobookshelf binds to. Most commonly, this will be 127.0.0.1 if you want the service to listen to localhost only, or left unset if you want to listen to all interfaces (both IPv4 and IPv6).
  • PORT
    • The TCP port Audiobookshelf will listen on.

Security

  • TOKEN_SECRET
    • Secret used for generating the JSON Web Tokens.
    • If none is provided, a secure random token is generated automatically. That will usually be sufficient.

Other

  • SOURCE
    • Installation source. Will be shown in the web client.
    • Usually set to docker, debian or rpm.

tagDirectory Structure

Here is an example supported directory structure for Books

Terry Goodkind

 - 

Sword of Truth

 -  - 

Vol 1 - 1994 - Wizards First Rule {Sam Tsoutsouvas}

 -  -  -  audiotrack

Audio Track 1.mp3

 -  -  -  audiotrack

Audio Track 2.mp3

 -  -  -  crop_original

Cover.jpg

 -  - 

Vol 2 - 1995 - Stone of Tears

 -  -  -  audiotrack

Audiobook.m4b

 - 

Heart of Black Ice - Sister of Darkness

 -  -  audiotrack

Audio File.m4a

Steven Levy

 - 

Hackers - Heroes of the Computer Revolution {Mike Chamberlain}

 -  -  audiotrack

Audio File.m4a

1945 - Animal Farm

 -  audiotrack

Audiobook.mp3

audiotrack

Animal Farm.m4b

Books are designated by folders. Any audio files (or ebook files) within a folder will be grouped into that book, except in the root folder where each audio file will be treated as an individual book.

tagAuthor Folder Naming

Supports "Last, First" author naming as well as multiple authors separated by ",", ";", "&" or "and".

Valid author folder names:

Ichiro Kishimi

Kishimi, Ichiro

Ichiro Kishimi, Fumitake Koga

Kishimi, Ichiro, Koga, Fumitake

Ichiro Kishimi & Fumitake Koga

Kishimi, Ichiro & Koga, Fumitake

Terry Goodkind, Ichiro Kishimi and Fumitake Koga

tagTitle Folder Naming

In addition to the book title, the title folder can include the publish year, series sequence, the subtitle, and the narrator.

Here are a bunch of ways the same book could be named:

Wizards First Rule

Wizards First Rule {Sam Tsoutsouvas}

1994 - Wizards First Rule

Wizards First Rule - A Really Good Subtitle

1994 - Book 1 - Wizards First Rule

1994 - Volume 1. Wizards First Rule {Sam Tsoutsouvas}

Vol 1 - 1994 - Wizards First Rule

1994 - Wizards First Rule - Volume 1

Vol. 1 - 1994 - Wizards First Rule - A Really Good Subtitle {Sam Tsoutsouvas}

(1994) - Wizards First Rule - A Really Good Subtitle

1 - Wizards First Rule

1. Wizards First Rule

  • Subtitle: Parsing out subtitles into a separate field is optional and must be enabled in settings. Subtitle must be separated by " - ".
  • Series Sequence: Case insensitive & decimals supported.
    • The sequence can be placed anywhere in the folder name.
    • It must be followed by " - " or ". "
    • If it is not at the beginning of the folder name, it must be preceded by " - " and "Vol" "Vol." "Volume" or "Book"
  • Publish Year: The publish year must be the first part of the name OR directly after a series sequence, and separated by " - " on both sides.
  • Narrator: Must be wrapped in curly braces. e.g. {Sam Tsoutsouvas}.
  • Discs and Disc Numbers: You have to name each folder in the format of CD1, CD01, or CD001; Disk Folder support is not fully supported yet.

tagAudio Metadata

Audiobookshelf uses the ID3 metadata tags in audio files to populate data.

priority_high

Data parsed from the folder structure and filenames takes priority over ID3 tags unless you have enabled the scanner setting "Prefer Audio Metadata".

Metadata on audio files will be mapped as follows (second tag after "/" is a fallback):

ID3 Tag  (case-insensitive) Audiobookshelf Data
artist / album-artist Author
album / title Title
subtitle Subtitle
publisher Publisher
year Publish Year
composer Narrator
description Description
genre Genres *
series / mvnm Series
series-part / mvin Series Sequence
language / lang Language
isbn ISBN
asin / audible_asin ASIN
Overdrive MediaMarkers Chapters**

* Genre meta tag can include multiple genres separated by "/", "//", or ";". e.g. "Science Fiction/Fiction/Fantasy"

** Chapter extraction from Overdrive MediaMarkers must be enabled in your server settings

Embedded cover art will be extracted and used only if there are no images in the book folder.

tagAudio Tracks

An audiobook contains tracks. Tracks are audio files assigned a track number.
The track number is parsed from the audio filename and from the ID3 tags of the audio file.
Audiobooks that are made up of multiple discs or cd's will be ordered first by disc number then by track number.

Key ID3 Tags  (case-insensitive)
TrackNumber track, trck, trk
DiscNumber discnumber, disc, disk, tpos

The scanner will choose the more accurate track/disc number between the filename and ID3 tag numbers.

Tracks can be manually ordered and enabled/disabled by pressing the "Manage Tracks" button on the audiobook page.

tagAdditional Metadata

If you have a file named desc.txt in the library item folder it will be used as the description.

If you have a file named reader.txt in the library item folder it will be used as the narrator.

If you have an OPF file with extension .opf in the library item folder it will be parsed.
Details extracted from OPF:

title
author
narrator
publishYear
publisher
isbn
description
genres
language
series
volumeNumber

tagDirectory Structure

Here is an example supported directory structure for Podcasts

Lex Fridman Podcast

 -  audiotrack

#219 – Donald Knuth.mp3

 -  audiotrack

#252 – Elon Musk.mp3

 -  crop_original

Cover.jpg

Self-Hosted

 -  audiotrack

#69 - Get Off My Lawn.mp3