A Docker-based web UI that combines audiobookshelf playback with Jackett/Transmission downloading - a unified "browse, request, download, play" experience.
┌─────────────────────────────────────────────┐
│ Librarian │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Playback │ │ Search │ │
│ │ (ABS API) │ │(Jackett) │ │
│ └─────────────┘ └─────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ Download (Transmission) │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌───────────┐ ┌────────────┐
│Audiobook │ │ Jackett │ │Transmission│
│ shelf │ │ :9117 │ │ :9091 │
│ :13378 │ └───────────┘ └────────────┘
└──────────┘
If you already have audiobookshelf, jackett, and transmission running, use this to iterate on Librarian separately:
# 1. Create .env with your API tokens
echo "ABS_API_TOKEN=your_audiobookshelf_token" > .env
echo "JACKETT_API_KEY=your_jackett_key" >> .env
# 2. Build and start Librarian
docker-compose -f docker-compose.librarian.yml up -d --buildThis uses network_mode: host and host.docker.internal to connect to your existing services on:
http://host.docker.internal:13378→ Audiobookshelfhttp://host.docker.internal:9117→ Jacketthttp://host.docker.internal:9091→ Transmission
If you want Librarian to manage everything in one compose file:
# Copy .env.example to .env and fill in your values
cp .env.example .env
# Start all services
docker-compose up -dAdd the following service to your existing docker-compose.yml:
librarian:
image: ghcr.io/yourusername/librarian:latest
container_name: librarian
networks:
- media
ports:
- 3000:3000
volumes:
- /mnt/disk1/appdata/librarian:/config
environment:
- PUID=1000
- PGID=1001
- TZ=Europe/London
- LIBRARIAN_ABS_URL=http://audiobookshelf:80
- LIBRARIAN_ABS_API_TOKEN=${ABS_API_TOKEN}
- LIBRARIAN_JACKETT_URL=http://jackett:9117
- LIBRARIAN_JACKETT_API_KEY=${JACKETT_API_KEY}
- LIBRARIAN_TRANSMISSION_URL=http://transmission:9091
- LIBRARIAN_TRANSMISSION_USERNAME=admin
- LIBRARIAN_TRANSMISSION_PASSWORD=admin
- LIBRARIAN_DOWNLOAD_PATH=/data/audiobooks
restart: unless-stopped
depends_on:
audiobookshelf:
condition: service_healthy
jackett:
condition: service_healthy
transmission:
condition: service_healthy| Environment Variable | Description | Default |
|---|---|---|
LIBRARIAN_ABS_URL |
Audiobookshelf URL | http://audiobookshelf:80 |
LIBRARIAN_ABS_API_TOKEN |
Audiobookshelf API token | - |
LIBRARIAN_JACKETT_URL |
Jackett URL | http://jackett:9117 |
LIBRARIAN_JACKETT_API_KEY |
Jackett API key | - |
LIBRARIAN_TRANSMISSION_URL |
Transmission URL | http://transmission:9091 |
LIBRARIAN_TRANSMISSION_USERNAME |
Transmission username | admin |
LIBRARIAN_TRANSMISSION_PASSWORD |
Transmission password | admin |
LIBRARIAN_DOWNLOAD_PATH |
Download path | /data/audiobooks |
- Log in to Audiobookshelf
- Go to your user settings (click your username)
- Click "Create Token" under API Tokens
- Copy the token
- Go to your Jackett UI
- Click the "API Key" button (top right)
- Copy your API key
Make sure Jackett is configured to download to the same folder that Audiobookshelf watches:
- In Jackett: Settings → Advanced → Downloads → Save to:
/downloads - This should map to
/mnt/disk1/downloads/audiobooksin Docker
# Backend
cd backend
uv sync
uvicorn app.main:app --reload --port 8000
# Frontend
cd frontend
npm install
npm run devThen access the frontend at http://localhost:3000 (proxies API to port 8000)
- Backend: FastAPI (Python)
- Frontend: Next.js + React + TailwindCSS
- Database: SQLite
MIT