Skip to content

Repository files navigation

Aldus icon Aldus

A self-hosted home for the books you own — ebooks and audiobooks, read together.

Status: beta License: MIT

TestFlight beta · Live demo · Documentation · Quickstart


Most people who own both an ebook and its audiobook edition live with two disconnected apps and no memory between them: close the book on your commute, lose your place when you pick up the audio that night. Aldus is a personal library server that finds your books, brings in the format you're missing, and keeps your exact position synchronized between reading and listening — down to the sentence, not just "roughly where you were."

It's built for the way a household actually keeps books. One person hosts it. Everyone else opens a title and reads or listens, without ever needing to know what a library, a source, or an indexer is. The person running it gets real controls — storage, download policy, permissions, backups. Everyone else gets a calm, book-shaped app that gets out of the way.


Current beta status

Aldus is public beta software. The source, self-hosted server, web app, and public demo are available now; anyone with an iPhone or iPad can join the public TestFlight beta. Android is implemented but does not yet have a public build. Expect rough edges and take a verified backup before upgrading a server you depend on.


Run the server

Every tagged release publishes a ready-to-run, multi-architecture image to GitHub Container Registry. There is nothing to build. docker compose up -d pulls ghcr.io/mahcks/aldus and starts serving — no Go toolchain, no Node, no local Dockerfile.

ALDUS_VERSION=0.1.0-beta.18
mkdir -p aldus/library-media aldus/downloads && cd aldus
curl -fL "https://github.com/Mahcks/Aldus/releases/download/v${ALDUS_VERSION}/compose.yml" -o compose.yml
printf 'ALDUS_VERSION=%s\n' "$ALDUS_VERSION" > .env
docker compose up -d --pull always
docker compose ps

Compose does not build Aldus or require the repository. It pulls the exact ghcr.io/mahcks/aldus:0.1.0-beta.18 image and adds the restart policy, persistent volumes, health check, and safe localhost port mapping that a long docker run command would need. When docker compose ps reports healthy, open http://localhost:8080 and create the first account — it becomes the administrator. Do that before exposing Aldus to another machine.

Current beta note: 0.1.0-beta.18 includes CPU alignment and publishes an optional NVIDIA CUDA image. Image downloads are large, so first startup time depends on your connection and host.

Prefer to look before downloading anything? demo.aldus.media runs the current build against a small public-domain catalog — no account required.


What it looks like

Aldus ebook reader showing a synchronized passage and a Listen from here action

Read with adjustable typography, layout, and an exact synchronized passage

Aldus audiobook player showing chapters, playback controls, and a synchronized read-along passage

Listen with chapters, saved progress, and a live read-along passage


Read↔listen sync that means it

When a book's ebook and audiobook are aligned, switching from reading to listening resumes at the same point in the text — not an approximate percentage rounded to the nearest chapter. The standard image runs WhisperX on CPU automatically in the background; an optional NVIDIA image accelerates the same work.

flowchart LR
    A[Reading on your phone] -->|close the book at 27%| B[(Aligned position store)]
    B -->|resume at the same sentence| C[Listening on the way home]
    C -->|pause the audio| B
    B -->|pick the book back up| A
Loading

Ask for what's missing, without the busywork

Point Aldus at your indexers and download client once, and an ordinary reader never has to think about either again.

flowchart LR
    U([Household member<br/>requests a format]) --> R{Aldus checks<br/>the owner's rules}
    R -->|within policy| P[Prowlarr searches<br/>configured indexers]
    P --> Q[qBittorrent<br/>downloads the release]
    Q --> V[Aldus verifies size,<br/>checksum, and format]
    V --> L[(Imported and<br/>ready to open)]
    R -->|needs approval| O[Library owner<br/>approves or declines]
    O --> P
Loading

Indexer names, file sizes, and release strings never surface to someone who just wants to read. They see plain-language status in Activity: searching, downloading, importing, ready. If nothing suitable exists yet, the request stays open and Aldus keeps watching — it never dead-ends silently.


Everything else Aldus does

A household, not just a user Libraries are access grants, not walls. Most setups need zero configuration; multi-library households — a shared collection plus a kids' library — get real isolation when they need it.
Bring what you already have Point Aldus at a folder of EPUBs and audio files and it imports them without renaming or rewriting a single file. Nothing you already own gets touched.
Two ways to store media External Sources stay exactly where they are, referenced read-only. Managed media from acquisitions is copied in, checksummed, and verified on import.
Read anywhere The web app ships with every server. The iOS app is available through the public TestFlight beta. Android is implemented but does not yet have a public beta distribution channel. OPDS + KOReader credentials support e-ink devices.
Verified backups docker compose run --rm aldus backup produces a checksummed archive of the database, managed media, covers, and alignment artifacts. The stored Prowlarr API key, qBittorrent password, and active sessions are removed from the archive.
It's yours Self-hosted, your data, on your hardware. No account required anywhere but your own server.

Choose how far you want to go

I want to… Set up… Then explore…
Browse books I already own One Library and one Source Home, Discover, and Collections
Read an EPUB An imported EPUB The title page, then Read
Listen to an audiobook Imported MP3/M4B audio The title page, then Listen
Test read/listen synchronization Matching ebook and audiobook Switching formats without losing your place
Request missing formats Prowlarr, qBittorrent, and library download rules Discover and Activity
Use KOReader A reader credential Account → KOReader and OPDS

Drop a few EPUB, MP3, M4B, or audiobook files into library-media/, then: open More → Libraries and create one, open More → Sources and add /library/media, start a scan, accept anything in Import review, and open a title from Home or Discover. You do not need Prowlarr or qBittorrent just to try the library and reader.

The Compose file mounts ./library-media read-only. Aldus indexes those files but never renames, moves, or rewrites them.


Set up automatic requests

This part is optional. Aldus currently works with Prowlarr to search your configured indexers and qBittorrent to download a selected release. Usenet clients aren't supported yet.

Open More → Acquisitions, connect both services, and test each connection. Then, per library, set default destinations, maximum size, allowed formats, preferred language, and whether abridged audiobooks are acceptable. Finally choose what each member may do: request a missing format, skip approval for compliant requests, or use advanced release choice instead of Aldus's guided pick.

For acquisitions, qBittorrent and Aldus must see the same completed-download folder. Set ALDUS_DOWNLOAD_PATH to the host folder qBittorrent uses, then set qBittorrent download root in Aldus to qBittorrent's container path (commonly /downloads).


Backups and upgrades

Create and download a verified backup from More → System → Data and recovery. The command line remains available for emergency recovery:

docker compose run --rm aldus backup \
  --archive /backups/aldus-backup-$(date +%Y%m%d).tar.gz

Restore while Aldus is stopped and /data is empty:

docker compose stop aldus
docker compose run --rm aldus restore \
  --archive /backups/aldus-backup-20260819.tar.gz \
  --data-dir /data
docker compose up -d

To update, take a backup, download the new release's compose.yml, change ALDUS_VERSION in .env, then run docker compose pull && docker compose up -d. This keeps the image and its deployment configuration on the same release. To roll back, restore the matching backup and use both the previous image version and previous Compose file. Aldus intentionally has no implicit latest fallback.


Using Aldus away from your server

The default Compose mapping is localhost-only. Before making it reachable elsewhere, create the first administrator and put Aldus behind an HTTPS reverse proxy. Set ALDUS_BIND_HOST=0.0.0.0 and ALDUS_SECURE_COOKIES=true when the proxy reaches Aldus over the host network. Trusted-LAN-only HTTP remains available for native clients on private IPs, but requires the explicit ALDUS_ALLOW_INSECURE_HTTP=true acknowledgement. Never expose that mode to the internet.

Optional NVIDIA acceleration

The standard Aldus image includes WhisperX and generates exact read/listen mappings on CPU without extra setup. CPU processing can take hours for a long audiobook. To accelerate it, install the NVIDIA driver and NVIDIA Container Toolkit, then run one command:

curl -fL https://github.com/Mahcks/Aldus/releases/download/v0.1.0-beta.18/compose.gpu.yml -o compose.gpu.yml
docker compose -f compose.yml -f compose.gpu.yml up -d --pull always

The override replaces the same aldus container and requests one GPU. Aldus selects CUDA, FP16, and a conservative memory profile internally. If CUDA is unavailable, the alignment job reports a useful error while the rest of Aldus remains available. Return to CPU processing with docker compose up -d --pull always.

For e-ink devices, create a credential under Account → KOReader and OPDS, then add the displayed /opds/ URL as an OPDS catalog and use the Aldus origin as KOReader's custom progress server. Keep KOReader's document matching method set to Binary; Aldus preserves native progress for every recognized EPUB and bridges it to read↔listen progress whenever an exact alignment is ready.


When something doesn't work

Aldus can't see my books — confirm the host folder is mounted, that the Source path is /library/media (not the host's original path), and that ALDUS_SOURCE_ROOTS includes the server-visible path.

A request doesn't start — test Prowlarr and qBittorrent under More → Acquisitions, confirm the library has default destinations for that format, and check whether the request is waiting on approval.

A download finished but the title is unavailable — confirm ALDUS_DOWNLOAD_PATH matches qBittorrent's folder, confirm qBittorrent download root is set correctly, and check More → Sources → Import review — Aldus asks for help when a completed payload is ambiguous or conflicts with an existing format.

Is the server healthy? /api/v1/health confirms the process is running; /api/v1/ready checks SQLite and data-directory write access.


Where this is headed

The ambition is a complete, calm home for the books you own — one that treats reading and listening as one continuous act instead of two apps that happen to share a title. Acquisition, alignment, and the household permission model are the parts still hardening the fastest, so expect them to change shape a little before things settle. Aldus is in beta and ready for focused real-world testing, but it is not yet a stable 1.0 release. If something doesn't add up, that report is exactly what's useful right now.

Aldus public demo landing page

Want to help build Aldus? Start with CONTRIBUTING.md.

About

A self-hosted library for ebooks and audiobooks with sentence-level read↔listen progress sync.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages