Skip to main content

Reading Pipeline

Chaptarr + CWA replace the old Bookshelf + Boundless setup.
Where it runs: All three services — Chaptarr, CWA, Audiobookshelf — run on i3 (debian-1) as Swarm services on the swarm overlay. The earlier “runs on Pentium / inside the gluetun namespace” description is obsolete; the Swarm migration moved them to i3 and put them on the overlay network. Traefik’s Swarm provider routes them via deploy.labels on *.augustin.ai — not the old traefik/dynamic/pentium-services.yaml file.
Status (updated 2026-06-07): Working. Chaptarr was upgraded 0.9.439 → 0.9.580, which fixed the import-matching failures (NO_MATCH_HOLY_GRAIL). Requests are driven by the Hardcover → Chaptarr bridge (chaptarr/hardcover-bridge.py, cron every 30 min) since Chaptarr’s native import list only adds catalog-new items. Reading is via Readest (OPDS off CWA) + KOReader; Readest also pushes progress/highlights back to Hardcover, closing the loop.

Pipeline (intended)

Hardcover library (Want to Read, Currently Reading)
  → hardcover-bridge.py (cron 30min) monitors+searches in Chaptarr   [replaces the native import list, which only adds catalog-new items]
    → Prowlarr searches 8 indexers (1337x, BitSearch, Internet Archive, Knaben, LimeTorrents, Nyaa.si, The Pirate Bay, TorrentGalaxy)
      → qBittorrent downloads via Gluetun VPN
        → Ebooks: /media/books/{Author}/{Title}/        [imports cleanly on Chaptarr 0.9.580]
          → Host cron copies new ebooks to CWA ingest folder
            → CWA auto-ingests into Calibre library
            → CWA auto-converts to epub
            → CWA enriches metadata from Hardcover
            → CWA serves OPDS catalog for KOReader
            → CWA syncs reading progress via KOSync
        → Audiobooks: /media/audiobooks/{Author}/{Title}/
          → Audiobookshelf picks them up

Components

ServiceImageNodeReplacesPurpose
Chaptarrrobertlordhood/chaptarr:latest (v0.9.580)i32× Bookshelf (Readarr)Unified ebook + audiobook acquisition
CWAcrocodilestick/calibre-web-automated:latesti3BoundlessCalibre library, OPDS, KOSync, metadata
Audiobookshelfghcr.io/advplyr/audiobookshelf:latesti3(unchanged)Audiobook streaming
Prowlarrlscr.io/linuxserver/prowlarr:latesti3Indexer manager (also a Swarm service)

How Chaptarr reaches the download stack

Chaptarr is on the swarm overlay, not inside gluetun’s network namespace, so it talks to the compose-only download stack over the overlay by service-DNS name:
  • Download client: gluetun:8085 (qBittorrent, published on the gluetun container)
  • Indexers: prowlarr:9696

Chaptarr → CWA Ingest

Ebooks reach CWA via one host cron (the dumb /media/torrents bypass was retired 2026-06-07 once Chaptarr’s matching became reliable):
  1. In-container custom scriptchaptarr/chaptarr-cwa-ingest.sh, mounted at /config/scripts/cwa-ingest.sh, wired as a Chaptarr “On Import” custom script. It does not work — its log only ever records Test events; the real import event never fires (Chaptarr notification bug). Dead weight, left in place harmlessly.
  2. Host cron downloads/cwa-ingest-cron.sh — every minute. Polls /mnt/main/media/books (where Chaptarr’s clean import lands files) for new ebooks and copies them to CWA’s ingest folder. This is the live handoff.
Retired: downloads/torrent-to-cwa.sh scraped raw /media/torrents (including whole series packs) straight into CWA, bypassing Chaptarr’s matching. It papered over import failures but polluted the library (e.g. one “Throne of Glass” request dumped 12 Sarah J. Maas books). Removed once Chaptarr 0.9.580 imported reliably; the clean /media/books path is the only ingest now.

CWA Features Enabled

  • OPDScalibre.augustin.ai/opds (authenticated)
  • KOReader sync — reading progress across devices
  • Kobo sync — KOReader Kobo protocol
  • Hardcover sync — metadata enrichment from Hardcover API
  • Hardcover auto-fetch — periodic metadata pulls
  • Auto-convert — target format: epub
  • Kindle EPUB fixer — fixes common epub issues
  • Duplicate auto-resolution — strategy: keep newest

Chaptarr Notes

  • Metadata server: api2.chaptarr.com (set in Settings → Development; api.chaptarr.com has SSL issues)
  • Hardcover JWT token stored in Chaptarr’s Config table (hardcoverapitoken, hardcoverenabled=True); valid into 2027. Shared conceptually with CWA for metadata.
  • API: http://chaptarr:8789/api/v1 on the overlay; X-Api-Key in chaptarr/config/config.xml. Note curl is not in the container — use wget -qO- for in-container API calls.

Known Issues

Verified 2026-06-04. These are why new books stopped flowing around 2026-03-14.
  1. Hardcover import list returns nothing. Chaptarr’s ImportListSyncService logs No list items to process every cycle. The import list is configured (Want to Read + Currently Reading, auto-add + search on, user augustin), but the per-list apiToken field is empty (DB-confirmed) even though the global Hardcover token is valid. Nothing new is being pulled in, so there’s nothing new to grab. 27 books sit in wanted/missing.
  2. NO_MATCH_HOLY_GRAIL import failures. Completed downloads fail to import in Chaptarr — three are stuck in the queue with importFailed / Rejected: NO_MATCH_HOLY_GRAIL (authorId=…). The downloaded files are orphaned under /media/torrents and never reach /media/books (so they never reach CWA either). Examples stuck: To Sell Is Human, Stillness Is the Key, Dungeon Crawler Carl 03.
  3. Indexer throttling. TorrentGalaxy returns 429 and self-disables for ~1 day; Knaben hits its API request limit; 1337x has RSS-sync gaps. Transient but recurring — narrows the indexer pool during searches.
  4. Triple/dead ingest (see above) — the in-container custom script never fires; the two host crons duplicate each other. Both cron logs went silent on 2026-03-14, consistent with nothing new importing into /media/books since then (not necessarily a cron failure).
  5. Library counts. Chaptarr DB: 2,370 book metadata rows, 43 monitored, 17 with files. CWA Calibre library: newest added timestamp is 2026-02-22.

Reading & cross-device sync (the honest map)

Readest was torn down 2026-06-07 — its self-host wasn’t worth it for the one thing it uniquely did (cross-device highlights). The current reality, source-verified against the CWA code, not assumed: CWA’s web reader and KOReader/KOSync are two separate progress stores. They do not cross-sync your exact reading position.
  • Web reader: position in browser localStorage + (manual bookmark only) a CFI in the bookmark table, keyed by Calibre book-id (cps/static/js/reading/epub-progress.js, cps/web.py:179).
  • KOSync: a separate kosync_progress table keyed by the file’s partial-MD5 content hash, storing KOReader’s xpointer (cps/progress_syncing/protocols/kosync.py).
  • Only crossover: a one-way, percent-only fallback Kindle → browser (a KOSync push writes a percent into KoboReadingState; the web reader jumps to it only if there’s no prior localStorage/bookmark). Browser → Kindle does not exist.
What syncs exact position: KOReader ↔ KOReader through CWA’s KOSync. Same epub from CWA OPDS → identical content hash → the real xpointer round-trips.
DeviceReaderExact position synced w/ Kindle?
KindleKOReader✅ CWA KOSync
PhoneKOReader (Android/iOS)✅ CWA KOSync
Linux laptopKOReader AppImage (koreader-v*-x86_64.AppImage)✅ CWA KOSync
Mac laptopCWA web reader (calibre.augustin.ai)❌ separate island — KOReader has no current macOS build (v2026.03 ships none)
Net: with a Mac + Kindle you get either exact cross-device position (live entirely in KOReader, which excludes the Mac) or a browser reader on the Mac (CWA web reader, an island) — not both, self-hosted. The product that did Mac-browser + Kindle + highlights together was hosted Readest.com (their cloud, not self-host). Practical setup: Kindle + phone on KOReader synced via CWA KOSync; Mac web reader is casual/occasional. Highlights stay per-device; Hardcover is one-way export only.

KOSync setup (per KOReader device)

KOReader’s built-in Progress sync plugin speaks the KOSync protocol — no extra plugin needed for progress:
  • Tools → Progress syncCustom sync serverhttps://calibre.augustin.ai/kosync
  • Register / Login with CWA credentials
  • Turn on automatically keep documents in sync; set document matching to binary (content hash) so the same file matches across devices.

KOReader → Hardcover Progress Sync