14 KiB
LazyLibrarian
🟢 Media Service
📋 Service Overview
| Property | Value |
|---|---|
| Service Name | lazylibrarian |
| Host | Atlantis (Synology) |
| Category | Media / Books |
| Difficulty | 🟡 |
| Docker Image | lscr.io/linuxserver/lazylibrarian:latest |
| Compose File | hosts/synology/atlantis/arr-suite/docker-compose.yml |
| Directory | hosts/synology/atlantis/arr-suite |
🎯 Purpose
LazyLibrarian is an ebook and audiobook download automation tool, similar to Sonarr/Radarr but for books. It monitors authors you follow, searches indexers for new releases, and automatically downloads them via SABnzbd or torrent clients. This is the replacement for the retired Readarr project.
🚀 Quick Start
Prerequisites
- Docker and Docker Compose installed
- Download client configured (SABnzbd and/or Deluge)
- Indexer access (via Prowlarr or direct)
- Access to the host system (Atlantis)
Deployment
# Navigate to service directory
cd hosts/synology/atlantis/arr-suite
# Start the service
docker-compose -f docker-compose.yml up -d lazylibrarian
# Check service status
docker-compose -f docker-compose.yml ps
# View logs
docker-compose -f docker-compose.yml logs -f lazylibrarian
🔧 Configuration
Docker Compose Configuration
lazylibrarian:
image: lscr.io/linuxserver/lazylibrarian:latest
container_name: lazylibrarian
environment:
- PUID=1029
- PGID=100
- TZ=America/Los_Angeles
- UMASK=022
- DOCKER_MODS=ghcr.io/themepark-dev/theme.park:lazylibrarian|ghcr.io/linuxserver/mods:lazylibrarian-calibre
- TP_SCHEME=http
- TP_DOMAIN=192.168.0.200:8580
- TP_THEME=dracula
volumes:
- /volume2/metadata/docker2/lazylibrarian:/config
- /volume1/data:/data
- /volume3/usenet:/sab
- /volume2/torrents:/downloads # Deluge download dir
- /volume2/metadata/docker2/lazylibrarian-scripts/custom-cont-init.d:/custom-cont-init.d
ports:
- "5299:5299"
networks:
media2_net:
ipv4_address: 172.24.0.5
security_opt:
- no-new-privileges:true
restart: always
Environment Variables
| Variable | Value | Description |
|---|---|---|
PUID |
1029 |
User ID for file permissions |
PGID |
100 |
Group ID for file permissions |
TZ |
America/Los_Angeles |
Timezone setting |
UMASK |
022 |
File permission mask |
DOCKER_MODS |
...theme.park:lazylibrarian|...mods:lazylibrarian-calibre |
Theme.park + Calibre (ebook-convert) |
TP_SCHEME |
http |
Theme.park scheme |
TP_DOMAIN |
192.168.0.200:8580 |
Theme.park host |
TP_THEME |
dracula |
Theme selection |
Port Mappings
| Host Port | Container Port | Protocol | Purpose |
|---|---|---|---|
| 5299 | 5299 | TCP | Web UI |
Volume Mappings
| Host Path | Container Path | Type | Purpose |
|---|---|---|---|
/volume2/metadata/docker2/lazylibrarian |
/config |
bind | Configuration files |
/volume1/data |
/data |
bind | Media library root |
/volume3/usenet |
/sab |
bind | Download directory |
🌐 Access Information
| Interface | URL |
|---|---|
| Web UI | http://192.168.0.200:5299 |
🔧 Initial Setup
1. Download Clients
SABnzbd Configuration:
| Setting | Value |
|---|---|
| Host | 192.168.0.200 |
| Port | 8080 |
| API Key | (from SABnzbd → Config → General) |
| Category | books |
Deluge Configuration (via Gluetun):
| Setting | Value |
|---|---|
| Host | 172.24.0.20 |
| Port | 8112 |
| Password | (your deluge password) |
2. Providers (Indexers)
Using Prowlarr (Recommended):
| Setting | Value |
|---|---|
| Host | 172.24.0.6 |
| Port | 9696 |
| API Key | (from Prowlarr → Settings → General) |
3. Processing Paths
| Setting | Value |
|---|---|
| eBook Library Folder | /data/media/ebooks |
| AudioBook Library Folder | /data/media/audiobooks |
| Download Complete Folder | /sab/complete |
📖 Adding Books
Via the Web UI
- Authors → Add Author → search by name → set to Active to track all their books
- Books → find the book → click Wanted to queue it for download
- LL searches indexers automatically on schedule (every 6h) or trigger manually: Tools → Search Wanted
API Access
| Field | Value |
|---|---|
| URL | http://192.168.0.200:5299 |
| API Key | REDACTED_LL_API_KEY |
| Config file | /volume2/metadata/docker2/lazylibrarian/config.ini (on Atlantis) |
Useful read/write CFG shortcuts:
# Read a config value
curl "http://192.168.0.200:5299/api?apikey=REDACTED_LL_API_KEY&cmd=readCFG&name=<NAME>&group=<Group>"
# Write a config value
curl "http://192.168.0.200:5299/api?apikey=REDACTED_LL_API_KEY&cmd=writeCFG&name=<NAME>&group=<Group>&value=<val>"
Via API
LL_API="http://192.168.0.200:5299/api?apikey=REDACTED_LL_API_KEY"
# 1. Find the book — returns bookid and authorid
curl "$LL_API&cmd=findBook&name=Book+Title+Author+Name"
# 2. Add it to the database
curl "$LL_API&cmd=addBook&id=<bookid>&wait=1"
# 3. Mark as Wanted (type=eBook or type=AudioBook)
curl "$LL_API&cmd=queueBook&id=<bookid>&type=eBook"
# 4. Trigger immediate search (don't wait 6h)
curl "$LL_API&cmd=forceBookSearch&type=eBook"
Language filter warning
LL may log Language [Unknown] does not match preference for some books — this is a warning only and does not block the download. The book will still be grabbed.
Flow after download
SABnzbd downloads → LL post-processor imports to library folder → Audiobookshelf watcher detects → available in ABS app.
🔒 Security Considerations
- ✅ Security options configured (no-new-privileges)
- ✅ Running with specific user/group IDs
- ✅ Theme.park integration for consistent UI
📊 Resource Requirements
Recommended Resources
- Minimum RAM: 256MB
- Recommended RAM: 512MB
- CPU: 1 core minimum
- Storage: Varies by library size
Resource Monitoring
docker stats lazylibrarian
🚨 Troubleshooting
Common Issues
Prowlarr reports "Applications unavailable due to failures" for LazyLibrarian
- Root cause: LazyLibrarian's API is disabled by default. Prowlarr requires the API to sync indexers.
- Fix: In LazyLibrarian → Config → General, enable the API and save. Copy the API key. In Prowlarr → Settings → Apps → LazyLibrarian, ensure the API key matches, then click Test.
- Error seen in Prowlarr logs:
LazyLibrarianException: LazyLibrarian Error - Code 501: API not enabled
Searches complete instantly with "found 0 books"
- Root cause: Newznab/Torznab providers are disabled by default (
ENABLED = Falsein source). The config.ini must haveenabled = trueexplicitly in each provider section. - Fix: Stop the container, add
enabled = trueas the first key under each[Newznab_N]and[Torznab_N]section in/config/config.ini, then restart.Script (docker stop lazylibrarian python3 /tmp/fix_ll_config.py # see script below docker start lazylibrarian/tmp/fix_ll_config.py):import re path = "/volume2/metadata/docker2/lazylibrarian/config.ini" with open(path) as f: lines = f.readlines() out = [] for i, line in enumerate(lines): out.append(line) if re.match(r"^\[(Newznab|Torznab)_\d+\]\s*$", line): j = i + 1 if not any(re.match(r"^enabled\s*=", l, re.I) for l in lines[j:j+10] if not l.startswith("[")): out.append("enabled = true\n") with open(path, "w") as f: f.writelines(out)
SABnzbd download stuck in "Grabbing" forever / Torrent grab fails with [Errno 2]
- Root cause: Newznab/Torznab provider hosts use the Docker container name (
prowlarr:9696). SABnzbd runs on the host network and can't resolve it; torrent grabs silently fail when LL can't reach the Prowlarr download URL, leaving it trying to open the result title as a file path. - Fix: Stop the container, replace
prowlarr:9696with192.168.0.200:9696in ALL providerhostentries (Newznab and Torznab), then restart.# Via Portainer API (container stop/start): curl -sk -X POST -H "X-API-Key: <portainer-token>" \ "https://192.168.0.200:9443/api/endpoints/2/docker/containers/<id>/stop" ssh atlantis "sed -i 's|http://prowlarr:9696/|http://192.168.0.200:9696/|g' \ /volume2/metadata/docker2/lazylibrarian/config.ini" curl -sk -X POST -H "X-API-Key: <portainer-token>" \ "https://192.168.0.200:9443/api/endpoints/2/docker/containers/<id>/start" -H "Content-Type: application/json" -d '{}'
SABnzbd not configured / "No NZB download method is enabled"
- Root cause: SABnzbd connection not set up in LazyLibrarian.
- Fix: Use the writeCFG API (or Config → Downloaders → SABnzbd in the UI):
SABnzbd API key:
LL_API="http://192.168.0.200:5299/api?apikey=<your-key>" curl "$LL_API&cmd=writeCFG&name=SAB_HOST&group=SABnzbd&value=192.168.0.200" curl "$LL_API&cmd=writeCFG&name=SAB_PORT&group=SABnzbd&value=8080" curl "$LL_API&cmd=writeCFG&name=SAB_API&group=SABnzbd&value=<sab-api-key>" curl "$LL_API&cmd=writeCFG&name=SAB_CAT&group=SABnzbd&value=books" curl "$LL_API&cmd=writeCFG&name=NZB_DOWNLOADER_SABNZBD&group=USENET&value=1"docker exec sabnzbd grep api_key /config/sabnzbd.ini
eBook library path not set / books import to /config
- Root cause:
EBOOK_DIRdefaults to empty, so imported books land in/config. - Fix: Set the library path:
Or in UI: Config → Processing → eBook Library Folder →
curl "http://192.168.0.200:5299/api?cmd=writeCFG&name=EBOOK_DIR&group=General&value=/data/media/ebooks&apikey=<key>"/data/media/ebooks
AudioBook library path not set / audiobooks import to /config
- Root cause:
AUDIO_DIRdefaults to empty, so imported audiobooks land in/configinstead of the Audiobookshelf-watched directory. - Fix: Set the library path:
Or in UI: Config → Processing → AudioBook Library Folder →
curl "http://192.168.0.200:5299/api?cmd=writeCFG&name=AUDIO_DIR&group=General&value=/data/media/audiobooks&apikey=<key>"/data/media/audiobooksVerify:curl "http://192.168.0.200:5299/api?apikey=<key>&cmd=readCFG&name=AUDIO_DIR&group=General"
Torrent download fails with [Errno 2] No such file or directory: '<result title>'
- Root cause: LL's
deluge.pyidentifies valid .torrent data by checking forb'announce'in the first 40 bytes. Tracker-less torrents (generated from magnet links by clients like go.torrent) start withd7:commentinstead, causing LL to fall back to treating the result title as a local file path. - Fix: A custom-cont-init.d script patches
deluge.pyon startup to also accept bencoded dicts (any data starting withd, which all valid .torrent files do). The patch and compose mount are already applied. Script at:/volume2/metadata/docker2/lazylibrarian-scripts/custom-cont-init.d/99-patch-deluge.sh
SAB_DIRECTORY cannot be set via writeCFG API
- Root cause:
writeCFGreturns OK butSAB_DIRECTORYis not written toconfig.iniby some LL versions (possible key mismatch). LL won't know where SABnzbd puts completed downloads and won't auto-import them. - Workaround: Manually trigger post-processing after a download completes:
This tells LL to scan the SABnzbd books category output dir and import any completed files.
curl "http://192.168.0.200:5299/api?apikey=REDACTED_LL_API_KEY&cmd=forceProcess&dir=/sab/complete/books"
KEEP_SEEDING setting does not persist
- Root cause:
writeCFGreturns OK forKEEP_SEEDINGbut the value is not actually saved. Manually editingconfig.inialso fails — LL reads config into memory at startup and writes it back on shutdown, overwriting manual edits made while the container is running. - Workaround: None found. The setting must be changed through the LL web UI (Config → Processing → Keep seeding after import), which writes it to the in-memory config.
NZB audiobook downloads deliver ebooks (epub/mobi) instead of audio files (m4b/mp3)
- Root cause: Some Prowlarr indexers (especially 1337x) classify audio releases under NZB categories. LL searches both NZB and Torznab for AudioBooks. An indexer may have an epub labeled as an audiobook at a high match percentage, and LL grabs it. The epub lands in the audiobook directory and is ignored by Audiobookshelf.
- Fix: If an audiobook download is an epub, check
docker logs lazylibrarianfor the grabbed URL, then mark the book as Wanted again and re-search. If the NZB result keeps winning, you may need to add the specific provider to a blocklist or manually grab a torrent via the UI.
Downloads not starting
- Verify download client connection in Config → Downloaders
- Check API keys are correct
- Ensure indexers are configured and working
Books not importing
- Check file permissions (PUID/PGID)
- Verify library paths are correct
- Manually trigger PostProcessor:
curl "$LL_API&cmd=forceProcess&dir=/sab/complete/books"
Metadata not found
- Try different metadata providers (Google Books, OpenLibrary, etc.)
- Search by ISBN if available
- Manual metadata entry
Useful Commands
# View real-time logs
docker logs -f lazylibrarian
# Restart service
docker restart lazylibrarian
# Update service
docker pull lscr.io/linuxserver/lazylibrarian:latest
docker restart lazylibrarian
# Access service shell
docker exec -it lazylibrarian /bin/bash
📚 Additional Resources
- Official Documentation: LazyLibrarian Wiki
- GitLab: LazyLibrarian/LazyLibrarian
- LinuxServer.io: Docker Image Docs
🔗 Related Services
Services REDACTED_APP_PASSWORD LazyLibrarian:
- Audiobookshelf (playback/serving)
- Calibre-Web (ebook management)
- SABnzbd (usenet downloads)
- Deluge (torrent downloads)
- Prowlarr (indexer management)
Last Updated: 2026-03-02 (Calibre mod, torrent patch, troubleshooting updates)
Configuration Source: hosts/synology/atlantis/arr-suite/docker-compose.yml