Libation is a headless Audible audiobook manager that periodically scans your Audible library and downloads your purchases as DRM-free audio files (M4B/MP3). It runs as a background daemon with no web UI — once configured it silently keeps your local library in sync.
The typical use case in this homelab is to feed downloaded books directly into the Audiobookshelf library at /mnt/Data/Media/Audiobooks.
Audible API
│
▼
libation (container)
│ reads credentials from /config/AccountsSettings.json
│ writes books to /data ──────────────────────────────▶ /mnt/Data/Media/Audiobooks
│ stores metadata in /db
│
└── no web UI, no ports, no Traefik — pure background daemon
Libation has no web interface. All management happens via configuration files that you place in the config volume before starting the container. After first-run account setup (see below) the container is fully autonomous.
/mnt/SSD/Containers/libation/configand/mnt/SSD/Containers/libation/dbmust exist on the host before first start./mnt/Data/Media/Audiobooksmust exist and be writable by PUID 3001.
mkdir -p /mnt/SSD/Containers/libation/{config,db}
chown -R 3001:3001 /mnt/SSD/Containers/libationThe Docker container is headless — it cannot prompt you for your Audible password or handle the login challenge interactively. You must complete the account setup using the desktop app first, then copy the resulting config files to the Docker volume. This only needs to happen once.
Download the latest release from GitHub and run it on any Windows, Mac, or Linux machine. When prompted to choose an interface, pick Chardonnay (the modern cross-platform UI). Do not install to Program Files on Windows — extract the zip to a user-owned folder instead.
- Open Libation and go to Accounts → Manage Accounts.
- Click Add Account and select your Audible locale (e.g., Amazon US).
- Enter your Amazon/Audible credentials. Audible may require a CAPTCHA or two-factor challenge — the desktop app handles this interactively. If login loops or fails, try the "Log in with browser" option which opens an external browser flow instead of the built-in form.
- Once authenticated, Libation will perform an initial library scan and populate your full book list.
Before copying the config, set up your download preferences in the desktop app so Settings.json captures them. In Settings → Download/Decrypt:
- Books folder — set this to anything; the Docker container ignores this value and uses
LIBATION_BOOKS_DIR(/data) instead. - File naming template — customize how downloaded files are named. A useful pattern:
This puts series-based books in a subfolder like
<if series-><series> - <-if series><title>The Stormlight Archive - The Way of Kings. - Output format — choose between keeping the original M4B (default, lossless) or converting to MP3. MP3 conversion is lossy and slower but maximizes compatibility. M4B plays natively on Apple devices and most modern players.
Locate the Libation settings directory on the machine where you ran the desktop app:
| OS | Path |
|---|---|
| Windows | %APPDATA%\Libation\ |
| macOS | ~/Library/Application Support/Libation/ |
| Linux | ~/.config/Libation/ |
Copy both files to the Docker config volume on TrueNAS:
# From your local machine (adjust source path for your OS)
scp "%APPDATA%\Libation\AccountsSettings.json" truenas:/mnt/SSD/Containers/libation/config/
scp "%APPDATA%\Libation\Settings.json" truenas:/mnt/SSD/Containers/libation/config/Then fix ownership on the host:
chown -R 3001:3001 /mnt/SSD/Containers/libation/configcp example.env .env # defaults are fine; adjust SLEEP_TIME if desired
docker compose up -d
docker compose logs -fA successful first scan looks like:
Scanning library for new books...
Found 142 books in library
Downloading: The Way of Kings (Part 1)...
Download complete: /data/Stormlight Archive/The Way of Kings.m4b
Once running, Libation is fully autonomous. Every SLEEP_TIME interval it:
- Scans your Audible library for new purchases or pre-orders that have become available.
- Downloads and decrypts any titles not already present in
/data. - Writes the final M4B (or MP3) file and a
.cuechapter file to the output directory.
Audiobookshelf will pick up new files automatically if its library scan is configured (or triggered manually).
# Live logs
docker compose logs -f libation
# See what's been downloaded
ls /mnt/Data/Media/Audiobooks/Audible tokens do eventually expire. If you see authentication errors in the logs:
- Open the desktop app on any machine and log in again.
- Re-copy
AccountsSettings.jsonto/mnt/SSD/Containers/libation/config/. - Restart the container:
docker compose restart libation
If you just bought a book and don't want to wait for the next scheduled scan:
docker compose restart libationThe container scans immediately on startup, then resumes its normal SLEEP_TIME loop.
Downloaded books land in /mnt/Data/Media/Audiobooks/ with the naming structure defined in Settings.json. Each title produces:
| File | Description |
|---|---|
<title>.m4b |
The audiobook audio (AAC, lossless from Audible) |
<title>.cue |
Chapter markers for players that support cue sheets |
M4B files are natively playable on Apple devices, VLC, and most modern media players. Audiobookshelf reads both the audio and chapter data.
| Variable | Default | Description |
|---|---|---|
TZ |
America/New_York |
Container timezone |
PUID |
3001 |
UID the container runs as (via user: directive) |
PGID |
3001 |
GID the container runs as |
SLEEP_TIME |
6h |
Scan interval. Duration string (30m, 6h, 24h) or -1 to run once and exit |
| Mount | Host Path | Purpose |
|---|---|---|
/config |
/mnt/SSD/Containers/libation/config |
AccountsSettings.json, Settings.json |
/db |
/mnt/SSD/Containers/libation/db |
Libation SQLite database |
/data |
/mnt/Data/Media/Audiobooks |
Downloaded audiobook files |
- No Traefik / no ports — this service has no web UI and is not in the port registry.
- User mapping — Libation's image defaults to UID 1001. This compose file overrides it with
user: "${PUID}:${PGID}"to match the rest of the homelab (3001:3001). If you see permission errors, confirm host directory ownership matches. - Books/InProgress paths in Settings.json are ignored — the container always uses the
LIBATION_BOOKS_DIRenv var (/data). Don't waste time trying to set the path inside the app. - SLEEP_TIME=-1 — use this if you prefer to drive scans from an external cron job rather than the container's internal loop.
- PostgreSQL — the
LIBATION_CONNECTION_STRINGenv var (not set here) lets you swap SQLite for PostgreSQL if you need remote access to the metadata.