# Set Up Audiobookshelf with Docker

> Install and run your own Audiobookshelf server using Docker or Docker Compose, the most common and recommended method

Source: https://soundleafapp.com/server/server-setup-docker/

---

Docker is the easiest way to get Audiobookshelf running. It works on Linux, macOS, and Windows, and updates are a single command.

## What you need

- **Docker Engine** installed on your machine ([get Docker](https://docs.docker.com/get-docker/))
- **A place for your audiobooks**: a folder on your machine with your audiobook files
- **A few minutes**. Seriously, that's it

## Quick start with Docker Compose

Create a `docker-compose.yml` file:

```yaml
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    container_name: audiobookshelf
    ports:
      - 13378:80
    volumes:
      - ./audiobooks:/audiobooks
      - ./podcasts:/podcasts
      - ./config:/config
      - ./metadata:/metadata
    environment:
      - TZ=America/Toronto  # Change to your timezone
    restart: unless-stopped
```

Then run:

```bash
docker compose up -d
```

Open `http://localhost:13378` in your browser. You'll be prompted to create your admin account.

That's it. You have an audiobook server.

## Or use Docker CLI directly

If you prefer a one-liner:

```bash
docker run -d \
  --name audiobookshelf \
  -p 13378:80 \
  -v /path/to/audiobooks:/audiobooks \
  -v /path/to/podcasts:/podcasts \
  -v /path/to/config:/config \
  -v /path/to/metadata:/metadata \
  -e TZ=America/Toronto \
  --restart unless-stopped \
  ghcr.io/advplyr/audiobookshelf:latest
```

Replace `/path/to/audiobooks` with the actual path to your audiobook files.

## What each volume does

| Volume | What it stores | Important notes |
|--------|---------------|-----------------|
| `/audiobooks` | Your audiobook files | Can be on network storage (NFS/SMB) |
| `/podcasts` | Your podcast files | Can be on network storage |
| `/config` | Database and settings | **Must be on local storage** (not network-mounted) |
| `/metadata` | Cache, covers, backups, logs | Can be on network storage |

> **Pro tip:** Keep `/config` on fast local storage. It holds the SQLite database and gets hit constantly. Putting it on a network share will make everything sluggish.

You can mount additional media directories if your audiobooks live in multiple places. Just add more `-v` lines.

## Organizing your audiobooks

Audiobookshelf is pretty smart about parsing folder names. The recommended structure:

```
/audiobooks
  /Author Name
    /Series Name
      /Book Title
        cover.jpg
        chapter1.mp3
        chapter2.mp3
```

It also reads ID3 tags from your audio files, so if your metadata is good, the folder structure matters less.

Some handy folder naming tricks that get parsed automatically:
- **Series sequence**: `Book 1 - Title` or `Vol. 3 - Title` (also `Volume 12. Title`, `6. Title`, `0.5 - Title`)
- **Publish year**: `2024 - Title`
- **Narrator**: `Title {Narrator Name}` (curly braces)
- **Subtitle**: `Title - Subtitle` (separated by dash)

## First-time setup

1. Open `http://YOUR-IP:13378` in a browser
2. Create your admin account
3. Click **Libraries** in the sidebar, then **Add your first library**
4. Select "Books" or "Podcasts" as the media type
5. Browse for your folder. Use the **container path** (e.g., `/audiobooks`), not the path on your host machine
6. Save, then click **Scan** in the library header to ingest your files (new books added later are picked up automatically by the file watcher)

## Updating

```bash
docker compose pull
docker compose down
docker compose up -d
```

Your data, settings, and progress are all stored in the mounted volumes, so updates are safe.

## Running as a specific user

If you need the container to run as a non-root user (common on NAS devices):

```yaml
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    user: "1000:1000"  # Your user's UID:GID
    # ... rest of config
```

Find your UID/GID with `id -u` and `id -g`.

## Common environment variables

| Variable | Default | What it does |
|----------|---------|-------------|
| `TZ` | System | Timezone (e.g., `America/Toronto`, `Europe/London`) |
| `PORT` | 80 (internal) | Internal listening port (you probably don't need to change this) |
| `ACCESS_TOKEN_EXPIRY` | 3600 | How long access tokens last (seconds) |
| `REFRESH_TOKEN_EXPIRY` | 2592000 | How long refresh tokens last (30 days) |

## Things that trip people up

- **Don't nest volumes.** Keep `/config`, `/metadata`, and your media directories separate. Nesting them inside each other causes weird issues.
- **Only change the external port.** If you want a different port, change the left side of the port mapping (e.g., `8080:80`). Never change the `80` on the right.
- **Network storage and the file watcher.** If your audiobooks are on NFS or SMB, the real-time file watcher may not pick up changes reliably. Set up a scheduled library scan as a fallback (Settings > Libraries > your library > Schedule).

## Next steps

- [Connect SoundLeaf to your server](https://soundleafapp.com/docs/getting-started/): get the iOS app set up
- [Set up a reverse proxy](https://soundleafapp.com/server/server-reverse-proxy/): access your server from outside your network
- [Cloudflare Access](https://soundleafapp.com/docs/cloudflare-access-setup/): secure remote access with Cloudflare tunnels
- [Tailscale VPN](https://soundleafapp.com/docs/tailscale-vpn-setup/): access your server over Tailscale
