DockerSelf-Hosting

Audiobookshelf with Docker: Your Own Audiobook and Podcast Server (Linux, Windows, Mac)

Before you start

  • 21 min read

Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#

Audiobookshelf is a free, self-hosted server for your own audiobooks and podcasts: you point it at folders of audio files, and you listen in a browser or in a phone app that remembers where you stopped.

Audiobookshelf official logo

Logo: the official Audiobookshelf project (github.com/advplyr/audiobookshelf)

It suits people who own audiobook files and want one library for the family, each person with their own progress. It also downloads podcast episodes. The project is active: its FAQ says "No, the project is not dead" and that a new version arrives about monthly.

WhatValue (official docs and release page, read November 2026)
Current versionAudiobookshelf v2.37.2, released 23 October 2026 (latest stable)
Image to pinghcr.io/advplyr/audiobookshelf:2.37.2 (the docs name this image and the :#.#.# tag form; the tag is on the registry)
Time neededAbout 20 minutes (our estimate, not measured)
RAM, CPU, diskNot documented by the project, so we give no numbers
PortTCP 13378 on your computer, which maps to port 80 inside the container
LicenceGPL-3.0
Project statusActive. Not archived, not renamed. The repository still lives under its author's account
Official docsaudiobookshelf.org/docs and the repository

At a glance:

  • What it is: one Docker container with a web player, an API for the apps, and a small database. Your audio files stay in your folders.
  • Folders matter: one folder per book. A wrong layout is the most common cause of "all my books show as one book".
  • Apps: the official Android app and iOS app are both in beta. The iOS beta is often full, but the web page also works as a phone app (PWA).
  • Away from home: the server has no built-in remote access. Use a VPN or an HTTPS reverse proxy, as the docs say.

How it fits together#

Your devices talk to one container. It reads your audiobook and podcast folders and writes only to its own config and metadata folders. Away from home, the phone joins your VPN first.

Diagram with two lanes: a phone, tablet or browser reaches Audiobookshelf directly at home, or through a VPN and optional Caddy HTTPS when away; Audiobookshelf reads the audiobooks folder, downloads into the podcasts folder and writes its config and metadata folders on the host

Drawn for this guide from the official Docker page and FAQ. Dashed boxes are optional.

Before you start#

You need a computer that stays on, Docker with Compose, and some audio files (or a podcast you want to follow).

SystemWhat you need
LinuxDocker Engine and the Compose plugin, curl
WindowsDocker Desktop and PowerShell
MacDocker Desktop and Terminal
Run in terminalbash
docker --version
docker compose version

Checklist:

  • [ ] Docker and Compose work (the two commands above)
  • [ ] Port 13378 is free on the computer
  • [ ] Your audio files are backed up (Audiobookshelf does not back up media)
  • [ ] The computer's own disk holds the config folder, not a network share (the docs warn about this)
  • [ ] For the HTTPS section only: a DNS name for the server and ports 80 and 443 free

Tested by DIY Lab Hub: not yet. The commands come from the official Docker page, the Dockerfile and the docs read in November 2026. We did not run them.

Step 1: Create the folders#

Audiobookshelf uses four folders. We keep them in ~/docker_volumes/audiobookshelf, as all DIY Lab Hub guides do.

Folder in the containerWhat it holds (from the docs)
/configThe SQLite database. Must be on the same computer, not a network share
/metadataCovers, author images, logs and backups
/audiobooksYour audiobooks (your choice of name)
/podcastsYour podcasts (your choice of name)

Linux#

Run in terminalbash
mkdir -p ~/docker_volumes/audiobookshelf/{config,metadata,audiobooks,podcasts,backups}
cd ~/docker_volumes/audiobookshelf
printf 'APP_UID=%s\nAPP_GID=%s\n' "$(id -u)" "$(id -g)" > .env
chmod 600 .env
cat .env

We create the folders ourselves so they belong to you. If Docker creates a missing folder it makes it owned by root, and a container running as your user then cannot write to it (issue #4471).

Windows (PowerShell)#

File contentpowershell
foreach ($d in 'config','metadata','audiobooks','podcasts','backups') {
  New-Item -ItemType Directory -Force "$HOME\docker_volumes\audiobookshelf\$d" | Out-Null
}
Set-Location "$HOME\docker_volumes\audiobookshelf"
"APP_UID=0`nAPP_GID=0" | Set-Content -Encoding ascii .env
Get-Content .env

Windows has no Linux user numbers. 0 keeps the official default, where the container runs as root. The docs do not cover Docker Desktop on Windows and we did not test it.

Mac (Terminal)#

Run in terminalbash
mkdir -p ~/docker_volumes/audiobookshelf/{config,metadata,audiobooks,podcasts,backups}
cd ~/docker_volumes/audiobookshelf
printf 'APP_UID=0\nAPP_GID=0\n' > .env
chmod 600 .env
cat .env

0 keeps the official default (root inside the container). The docs do not cover Docker Desktop on Mac and we did not test it. If a mount fails, check that Docker Desktop may share your home folder.

Check it worked. cat .env (or Get-Content .env) shows two numbers, and the five folders exist (ls, or Get-ChildItem in PowerShell).

Tip: Do not put /config on a network drive or another computer's share. The docs say the server may seem fine but will be slow and will eventually corrupt its database.

Step 2: Write the Compose file and start Audiobookshelf#

This is the official compose example with four changes: the image is pinned to 2.37.2, the folders sit next to the file, the user comes from .env, and the time zone is set. Replace Etc/UTC with your own zone, such as Europe/London. The official file maps 13378:80 and says to change only the left-hand number if you need another port.

Linux#

Run in terminalbash
cd ~/docker_volumes/audiobookshelf
cat > docker-compose.yml << 'EOF'
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:2.37.2
    container_name: audiobookshelf
    restart: unless-stopped
    user: "${APP_UID}:${APP_GID}"
    ports:
      - "13378:80"
    environment:
      - TZ=Etc/UTC
    volumes:
      - ./config:/config
      - ./metadata:/metadata
      - ./audiobooks:/audiobooks
      - ./podcasts:/podcasts
EOF
docker compose up -d
docker compose ps
docker compose logs --tail=50 audiobookshelf

Windows (PowerShell)#

Codepowershell
Set-Location "$HOME\docker_volumes\audiobookshelf"
@'
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:2.37.2
    container_name: audiobookshelf
    restart: unless-stopped
    user: "${APP_UID}:${APP_GID}"
    ports:
      - "13378:80"
    environment:
      - TZ=Etc/UTC
    volumes:
      - ./config:/config
      - ./metadata:/metadata
      - ./audiobooks:/audiobooks
      - ./podcasts:/podcasts
'@ | Set-Content -Encoding ascii docker-compose.yml
docker compose up -d
docker compose ps
docker compose logs --tail=50 audiobookshelf

Mac (Terminal)#

Same commands as Linux.

Check it worked. docker compose ps shows audiobookshelf running. The server's /status answers with JSON; a fresh install should say "isInit":false (expected shape, read from the source at v2.37.2, not run by us):

Run in terminalbash
curl http://localhost:13378/status
File contenttext
{"app":"audiobookshelf","serverVersion":"2.37.2","isInit":false, ...}

On Windows use curl.exe instead of curl. The docs do not recommend a Docker health check; the image has wget but no curl.

Tip: Do not copy PUID and PGID from other Docker guides. The docs say Audiobookshelf does not use them. Only the user: line sets the user.

Step 3: Create your account and your first library#

The first visit creates the admin. There is no default username or password (docs FAQ), so any admin / admin advice you read is wrong.

Linux#

On the server open http://localhost:13378. From another computer use http://<server-address>:13378.

Run in terminalbash
xdg-open http://localhost:13378

Windows (PowerShell)#

Codepowershell
Start-Process http://localhost:13378

Mac (Terminal)#

Run in terminalbash
open http://localhost:13378

Choose a root username and a long password, then add a library:

  1. Choose the library type: Books for audiobooks, Podcasts for podcasts. Each type has its own folder rules (Step 4).
  2. Name it, then pick the folder. Use the paths inside the container (the right-hand side of each mount): /audiobooks or /podcasts.
  3. Save. The server scans the folder. After that, a file watcher or a periodic scan (both in the library settings) finds changes.

Check it worked. You can log in, the library appears, and curl http://localhost:13378/status now shows "isInit":true.

Tip: Save the root password in a password manager before you close the page. If you lose it, the docs say you must edit the SQLite database by hand with the server stopped.

Step 4: Lay out your audiobooks and podcasts#

This is the step that decides how happy you are. The README puts it plainly: "Directory structure and folder names are important to Audiobookshelf."

Books. A book is a folder. A single-file book may sit at the library root; anything else needs its own folder. The format is {Author}/{Series}/{Book} or {Author}/{Book}:

Codetext
audiobooks/
  Jane Author/
    Example Series/
      Vol 1 - 2020 - First Book {Narrator Name}/
        Chapter 01.mp3
        Chapter 02.mp3
        cover.jpg
      Vol 2 - 2021 - Second Book/
        Second Book.m4b
    A Standalone Book/
      Audio.m4a

The docs list what a folder name can carry:

In the folder nameExampleBecomes
Series number1 - Title, Vol 1 - ..., Book 2 - ...Series order (decimals work)
Year1994 - TitlePublish year
Narrator in curly braces{Sam Tsoutsouvas}Narrator
Disc folders inside a bookDisc 1, CD 2Track order
ASIN in brackets[B002V0QK4C]Match key for Audible lookups

Authors can be First Last or Last, First, several split with ,, ;, & or and. Audio tags (ID3) fill in the rest; desc.txt, reader.txt, .opf or .nfo files can add a description or narrator.

Podcasts. A podcast is a flat folder with one audio file per episode. There are no season folders. A cover image goes in the same folder:

Codetext
podcasts/
  My Podcast/
    Episode 12.mp3
    Episode 13.mp3
    cover.jpg

You can also add a podcast in the web page by name, RSS link or OPML file. The server only shows episodes it has downloaded. Automatic episode checks are off until you enable them per podcast.

Create a sample folder:

Linux#

Run in terminalbash
cd ~/docker_volumes/audiobookshelf
mkdir -p "audiobooks/Jane Author/Example Series/Vol 1 - 2020 - First Book {Narrator Name}"
ls -R audiobooks

Copy a real audio file into it, then scan the library.

Windows (PowerShell)#

Codepowershell
Set-Location "$HOME\docker_volumes\audiobookshelf"
New-Item -ItemType Directory -Force "audiobooks\Jane Author\Example Series\Vol 1 - 2020 - First Book {Narrator Name}" | Out-Null
Get-ChildItem -Recurse audiobooks

Mac (Terminal)#

Same commands as Linux.

Check it worked. After the scan the book shows in the library with author "Jane Author" and series "Example Series", once an audio file is inside.

Tip: Tell your file manager or tagging tool to wait before you move files. The FAQ says moving files while the watcher is on can merge books into one.

Step 5: Connect the phone apps#

Both official apps need a running server and are described by the project as beta. The web page also works on a phone, and you can save it as a Progressive Web App (no offline listening).

AppWhereStatus (docs, November 2026)
AndroidGoogle PlayBeta, more features than iOS
iOSTestFlightBeta; the README says "beta is full" because Apple limits it to 10,000 testers

If TestFlight is full, the FAQ lists three options: the web page or PWA, sideloading the official app (AltStore or SideStore), or a third-party app. Third-party apps are not supported by the project.

In the app, enter your server address and log in with your account. You need the server's address on your home network:

Linux#

Run in terminalbash
hostname -I

Use the first address, for example http://<server-address>:13378.

Windows (PowerShell)#

Codepowershell
Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.PrefixOrigin -ne 'WellKnown' -and $_.IPAddress -ne '127.0.0.1' } | Select-Object InterfaceAlias,IPAddress

Mac (Terminal)#

Run in terminalbash
ipconfig getifaddr en0

If it prints nothing, try en1.

Check it worked. The app connects, shows your library and starts a book. Pause it, open the web page on your computer, and check your place matches.

Tip: Use one address in the app, the same one at home and away. The docs say progress syncs only when you use the same connection profile, so a home-address profile and a VPN profile do not share progress.

Step 6: Listen away from home with a VPN#

The docs say Audiobookshelf has no built-in remote access and serves plain HTTP. For one household a VPN is simplest: nothing is opened to the internet except the VPN's own port.

With either one, your phone joins the VPN, and you open the server by its VPN address in the app. Do not forward port 13378 on your router.

Linux#

From a Linux client on the VPN:

Run in terminalbash
curl http://<vpn-address-of-server>:13378/status

Windows (PowerShell)#

Run in terminalpowershell
curl.exe http://<vpn-address-of-server>:13378/status

Mac (Terminal)#

Run in terminalbash
curl http://<vpn-address-of-server>:13378/status

Check it worked. The command prints the same JSON as before, with "isInit":true, from outside your home network.

Tip: Test the VPN connection once before a trip, with the same address you will use in the app, not at the airport.

Put it behind HTTPS (with or without Traefik)#

If you want a name such as https://books.<your-domain> that works in every browser and app without a VPN, put a reverse proxy in front. Home-only users on a VPN can skip this section. The docs add two notes for any proxy: it must pass WebSocket traffic, and a subfolder works only as /audiobookshelf. Both routes need a DNS record pointing to the server.

With Traefik#

On a server that already runs Traefik v3 with the Docker provider, add labels and drop the host port.

This assumes an external Docker network called proxy and an entrypoint called https; use your own names. Create the network once:

Run in terminalbash
docker network create proxy

Replace docker-compose.yml with this file. The container port is 80, as in the official file:

File contentyaml
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:2.37.2
    container_name: audiobookshelf
    restart: unless-stopped
    user: "${APP_UID}:${APP_GID}"
    environment:
      - TZ=Etc/UTC
    volumes:
      - ./config:/config
      - ./metadata:/metadata
      - ./audiobooks:/audiobooks
      - ./podcasts:/podcasts
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.audiobookshelf.rule=Host(`books.<your-domain>`)"
      - "traefik.http.routers.audiobookshelf.entrypoints=https"
      - "traefik.http.routers.audiobookshelf.tls=true"
      - "traefik.http.services.audiobookshelf.loadbalancer.server.port=80"

networks:
  proxy:
    external: true

The Traefik docs page for Audiobookshelf has one warning: do not add the CORS headers accessControlAllowMethods, accessControlAllowOriginList or accessControlMaxAge to this router. They make login fail with "Unknown Error".

Start it with docker compose up -d in ~/docker_volumes/audiobookshelf.

Check it worked. curl -I https://books.<your-domain>/ returns an HTTP status line over HTTPS, and the web page opens with a valid certificate.

Without Traefik: Caddy#

Choose this if you have no Traefik. Caddy gets and renews its own certificates.

CaseWhat Caddy does
Public domainGets a Let's Encrypt certificate. Needs a DNS record to the server and ports 80 and 443 open
Home onlytls internal: Caddy signs its own certificate; you trust its root once per device

Caddy reaches Audiobookshelf by container name on the shared proxy network, so no host port is needed. Use the Traefik file above without its labels: lines. Then create Caddy; we mount the folder conf, not a single file, as Caddy's Docker docs advise:

Run in terminalbash
docker network create proxy
mkdir -p ~/docker_volumes/caddy/{conf,data,config}
cd ~/docker_volumes/caddy

On Windows PowerShell use New-Item -ItemType Directory -Force "$HOME\docker_volumes\caddy\conf","$HOME\docker_volumes\caddy\data","$HOME\docker_volumes\caddy\config". Save as docker-compose.yml there (caddy:2.11.8 was the newest image tag on Docker Hub on 5 November 2026):

File contentyaml
services:
  caddy:
    image: caddy:2.11.8
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"
    volumes:
      - ./conf:/etc/caddy
      - ./data:/data
      - ./config:/config
    networks:
      - proxy

networks:
  proxy:
    external: true

Save as conf/Caddyfile. For a public domain (the project's Caddy page uses encode gzip zstd and reverse_proxy):

File contenttext
books.example.com {
    encode gzip zstd
    reverse_proxy audiobookshelf:80
}

For a home-only name:

File contenttext
books.home.arpa {
    tls internal
    encode gzip zstd
    reverse_proxy audiobookshelf:80
}

Caddy's docs say its reverse proxy supports WebSocket connections without extra settings. Start both stacks with docker compose up -d in ~/docker_volumes/caddy and ~/docker_volumes/audiobookshelf. For tls internal, trust Caddy's root certificate on each device; Caddy as a reverse proxy has the Linux, Windows and Mac commands.

Check it worked. curl -I https://books.example.com/ returns an HTTP status line over HTTPS. For a home-only name the browser shows a padlock once the root is trusted. In the app, change the server address to the HTTPS name.

Security and testing#

Once the server is reachable from outside it is a login page on the internet. These controls matter most.

ControlHow
PasswordsA long, unique root password. Give each person their own account; the docs say shared accounts are not supported
PortsPublish only 13378 on a trusted network, or no host port behind a proxy. Never forward it on the router
Login limitThe docs list RATE_LIMIT_AUTH_MAX (default 40 attempts per 10 minutes). Do not set it to 0 on a public server
Config folder~/docker_volumes/audiobookshelf/config holds the database with password hashes. Readable only by you
Podcast downloadsA filter blocks requests to local addresses (SSRF protection). Switch it off only if you host a podcast on your own network

Quick tests on Linux after each change:

Run in terminalbash
cd ~/docker_volumes/audiobookshelf
docker compose ps
docker compose logs --tail=100 audiobookshelf
curl http://localhost:13378/status

What leaves the machine: podcast downloads from your feeds, and metadata lookups only when you press Match (the docs say a scan never fetches them). The README mentions chapter lookup with the Audnexus API. We did not audit the code for other traffic.

Common mistakes#

These come from the official docs' own warnings, GitHub issues and common AI assistant answers.

MistakeWhy it happensDo this instead
Putting /config on a network share or another computerIt looks fine at first. The docs say it then gets slow and eventually corrupts the SQLite databaseKeep /config on the same computer's own disk. Put only audio files on the NAS
One mount inside another, such as /audiobooks/podcastsThe mount points overlapGive every mount its own separate folder
Letting Docker create the folders, then adding user: 1000:1000Docker makes missing bind folders as root, so the user cannot write. Issue #4471 (open) shows the EACCES errorCreate the folders yourself first (Step 1). A reply in the issue says the server needs write access to /config and /metadata
Every book appears as one bookA book file sits loose in an author folder, or files were moved during a scan. The FAQ explains thisOne folder per book. Remove the wrong item in the web page, fix the folders, rescan. Progress for that item is lost
Reverse proxy without WebSocketsIssue #4267 (closed): "Socket unable to connect" behind nginx. A reply says WebSockets were not configuredUse Caddy or Traefik as in this guide, or add the WebSocket upgrade lines to nginx
CORS headers on the Traefik routerAdded for other apps. The docs say login then shows "Unknown Error"Remove accessControlAllowMethods, accessControlAllowOriginList and accessControlMaxAge from this router
One app profile for home and another for the VPNEasy to add both. The docs say progress does not sync between profilesUse one address everywhere. Go through the VPN or HTTPS name even at home
Upgrading on latest without reading notesIssue #5637 (closed): 2.37.1 crash-looped with EPERM ... copyfile ... /config/migrations on a non-root ZFS setup. The 2.37.2 notes list the fixPin the tag, read the release notes, back up first (Updates and backups)
Running backups while a phone syncsIssue #4572 (open): a 2 AM backup crashed the server with SQLITE_BUSY while a phone was updating its positionChoose a quiet backup hour and check docker compose ps the next morning
Restoring a Windows backup on LinuxThe docs say backups only restore on the same kind of installRestore on the same OS, or follow the docs' migration page. It stores absolute paths, so keep /audiobooks the same
Adding a podcast hosted on your own networkThe SSRF filter blocks local addresses by designSet DISABLE_SSRF_REQUEST_FILTER=1 only for that case
AI assistants: adding PUID, PGID or an admin / admin loginAssistants copy patterns from other apps. The docs say the image ignores PUID and PGID, and there is no default loginUse user: for the user, and create your own root account on first visit
AI assistants: inventing a Docker Hub image name or a different port mappingMany guides use other images or 80:80. The docs name only ghcr.io/advplyr/audiobookshelf and 13378:80Copy the image and port lines from this guide or the official page

Tip: Before running a compose file from a forum, check three things against the official page: the image name, the :80 inside port and the four mounts. That catches most broken setups.

Tip: After every change run docker compose logs --tail=100 audiobookshelf. Most errors print there with the exact text.

Troubleshooting#

ProblemSolution
Container restarts in a loopdocker compose logs --tail=100 audiobookshelf. If it says EACCES, fix the owner of config and metadata (sudo chown -R $(id -u):$(id -g) config metadata)
Error: Cannot find module '/index.js' or MODULE_NOT_FOUND after an updateA manager cached the old image. Re-create the container (Synology Container Manager: Reset; Portainer: Recreate). With plain Compose run docker compose pull, docker compose down, docker compose up -d
Web page works but shows "Socket unable to connect"The proxy does not pass WebSockets. Use the Caddy file in this guide (issue #4267)
"Socket failed to connect" only after an SSO loginReported behind nginx with an Authelia login (issue #4403, open). Check your proxy rules for the socket path, and log in with a password to compare
Cover or author images fail with "Call to ... is blocked"Reported on Docker Desktop (issue #3257, closed). A reply suggested adding sysctls: [net.ipv6.conf.all.disable_ipv6=1]. Also see the podcast SSRF row in Common mistakes
A .m4b file will not scan and the log shows SyntaxError: Expected property name or '}' in JSONThe file may use the xHE-AAC codec, which older FFmpeg cannot read. Re-encode it to AAC or Opus (docs FAQ)

Known bugs (open, November 2026)#

  • Issue #4471: non-root start fails when Docker created the folders as root. Create them yourself.
  • Issue #4572: a backup running while a client syncs can end the server with SQLITE_BUSY.
  • Issue #4403: "Socket failed to connect" after an Authelia login behind nginx.

Updates and backups#

Update. Read the release notes, change the tag in docker-compose.yml, then (the official commands):

Run in terminalbash
cd ~/docker_volumes/audiobookshelf
docker compose pull
docker compose down
docker compose up --detach
docker compose logs --tail=100 audiobookshelf

Backups, two layers. The server has its own backup feature. By default it writes to /metadata/backups; you can set how many to keep and a size limit (0 means unlimited). It saves the database and cover images, not your audio files. Back up your audio files with another tool, for example our restic guide.

For a copy of the whole config and metadata folders, stop the container so the database is not changing, archive, and start again.

Linux#

Run in terminalbash
cd ~/docker_volumes/audiobookshelf
docker compose down
tar -czf "backups/audiobookshelf-$(date +%F).tar.gz" config metadata
chmod 600 backups/audiobookshelf-*.tar.gz
docker compose up -d

To run it nightly at 03:00, add a crontab entry (crontab -e) with the same commands in a small script. Keep one copy on another machine.

Restore test. Unpack one archive into a new empty folder, never over the live one, and check that the database is there:

Run in terminalbash
mkdir -p /tmp/abs-restore-test
tar -xzf backups/audiobookshelf-<date>.tar.gz -C /tmp/abs-restore-test
ls /tmp/abs-restore-test/config

The docs' manual restore of a built-in backup: stop the server, unzip the newest file in metadata/backups, copy audiobookshelf.sqlite into config, copy metadata-authors and metadata-items to metadata/authors and metadata/items, start the server.

Windows (PowerShell)#

Save the script as backups\backup.ps1, then schedule it:

Codepowershell
Set-Location "$HOME\docker_volumes\audiobookshelf"
@'
Set-Location "$HOME\docker_volumes\audiobookshelf"
docker compose down
$stamp = Get-Date -Format yyyy-MM-dd
Compress-Archive -Path config,metadata -DestinationPath "backups\audiobookshelf-$stamp.zip" -Force
docker compose up -d
'@ | Set-Content -Encoding ascii backups\backup.ps1
schtasks /Create /SC DAILY /ST 03:00 /TN "Audiobookshelf backup" /TR "powershell -NoProfile -File $HOME\docker_volumes\audiobookshelf\backups\backup.ps1"

For a restore test, expand one zip into a new folder with Expand-Archive and look inside.

Mac (Terminal)#

Same commands as Linux, with date +%F working the same. For the schedule, use cron or a launchd job.

Performance and resources#

The project publishes no memory, CPU or disk figures, so this guide gives none. Measure your own server:

  • Resources: docker stats audiobookshelf shows live CPU and memory.
  • Files: MP3 plays almost everywhere; M4B gives one file per book. The FAQ says the server has open issues with seeking inside very long MP3 files.
  • Transcoding: the image contains FFmpeg, and the docs mention transcoding during playback for some codecs.

FAQ#

Is Audiobookshelf free to use? Yes, under GPL-3.0. The server and the apps are open source.

Is the project still maintained, renamed or archived? It is maintained: v2.37.2 came out on 23 October 2026, and the project's FAQ says a version arrives about monthly. It is not archived and has not been renamed. The author's account still hosts the code, and the web client is being rewritten in React.

Does it work on Mac? Through Docker Desktop. The docs list native installs for Windows and Linux only, and we did not test Docker Desktop on Mac or Windows.

Can several people use it? Yes. Create one account per person. Each keeps their own progress.

Sources#

Checked against the official docs on 2026-11-05.