Při výběru mezi Kavitou a Calibre-Web nerozhoduje ani tak vzhled rozhraní, jako spíš způsob, jakým mte knihy uložené ve složce /mnt/data/Knihy a jakou čtečku používáte.

Zatímco Audiobookshelf si prostě přečte soubory ze složky tak, jak jste je tam přes Sambu nahráli, u e-knih se obě aplikace pod kapotou chovají zcela odlišně:

Vlastnost Kavita Calibre-Web
Práce se soubory na SMB Nativní složky (stejně jako Audiobookshelf). Nahraješ EPUB přes SMB do /mnt/data/Knihy a Kavita ho hned zaindexuje. Vyžaduje databázi metadata.db. Neumí jen tak číst běžné složky, knihy se musí importovat přes Calibre.
Ideální čtečka pro Eriku PocketBook, Kobo, Onyx Boox (nativní podpora OPDS katalogu nebo webu přímo ve čtečce). Amazon Kindle (uzavřený systém bez OPDS, kde vítězí funkce Send to Kindle přes e-mail).
Posílání do Kindle e-mailem Ano (přidáno v novějších verzích přes vlastní SMTP). Ano (historicky hlavní tahák aplikace).
Konverze formátů (EPUB -> MOBI/AZW3) Ne (pouze čte a servíruje to, co leží na disku). Ano (ve spojení s nástrojem Kepubify nebo binárkou Calibre).
Komiksy, manga a PDF Špičková podpora (blesková čtečka přímo v prohlížeči). Základní podpora.

Architektonický chyták u Calibre-Web

Pokud ve složce /mnt/data/Knihy máte jen volně roztříděné soubory a podsložky (a nikoliv knihovnu vytvořenou desktopovým programem Calibre se souborem metadata.db), samotný Calibre-Web knihy nenačte.

  • Pokud byjste chtěli jít cestou Calibre-Webu bez nutnosti zapínat desktopové Calibre na PC, nasazuje se dnes jeho moderní fork Calibre-Web Automated (CWA). Ten má speciální složku ingest – co do ní přes SMB hodíte, to sám zpracuje, zapíše do databáze a přesune do knihovny. Má to ale háček: sám přerovná a přejmenuje soubory na disku podle pravidel Calibre (Autor/Název knihy (ID)/kniha.epub).

Proč Kavita u mě vyhrála

  1. Kavita nesahá na strukturu složek: Funguje navlas stejně jako Audiobookshelf. Hodíte knihu přes Sambu do /mnt/data/Knihy, Kavita ji oskenuje, stáhne metadata a na samotný soubor na disku nesáhne.
  2. Umí už i Send-to-Kindle: Pokud si v Kavitě nastavíte SMTP (např. přes svůj Gmail aplikační klíč), může te jedním kliknutím poslat knihu i do čtečky Kindle úplně stejně jako v Calibre-Webu.

Návrh docker-compose.yml pro IaC repozitář (Kavita)

Rozhodj jsem se řídit se stejným bezpečnostním standardem jako Audiobookshelf – přidělíme jí další unikátní UID (1107) a připojíme ji do společné skupiny media_shared (2000):

services:
  kavita:
    image: jvmilazz0/kavita:latest
    container_name: kavita
    environment:
      - PUID=1107  # Unikátní UID vyhrazené pro Kavitu
      - PGID=2000  # Společná skupina media_shared pro přístup na SMB disk
      - TZ=Europe/Prague
    ports:
      - 5000:5000
    volumes:
      - /opt/docker-stacks/kavita/config:/kavita/config
      - "/mnt/data/Knihy:/books"
    restart: unless-stopped

Pro kombinaci PocketBooku a mobilu je Kavita jednoznačný vítěz. Zatímco Kindle je uzavřený ekosystém odkázaný hlavně na e-mail, PocketBook je mnohem otevřenější a v kombinaci s Kavitou nabídne Erice hned tři pohodlné způsoby, jak číst:

  • 1. Čtení na mobilu (Webová čtečka / PWA): Kavita má špičkovou vestavěnou čtečku přímo v prohlížeči. Erika si může web Kavity na mobilu přidat na plochu jako aplikaci (PWA). Když čte EPUB nebo PDF v prohlížeči, Kavita si pamatuje přesnou stránku i odstavec, umožňuje měnit fonty, okraje i tmavý režim.
  • 2. Z mobilu rovnou do PocketBooku (Send-to-PocketBook): PocketBook má skvělou nativní službu Send-to-PocketBook každá čtečka dostane vlastní e-mailovou adresu (ve tvaru neco@pbsync.com). V Kavitě si Erika na mobilu vybere knížku (vypadá to jako katalog Netflixu), klikne na „Send to Device“ a kniha jí přes Wi-Fi sama přistane přímo v knihovně PocketBooku.
  • 3. Přímé stahování ve čtečce (OPDS nebo prohlížeč): Kavita plně podporuje protokol OPDS. Pokud má Erika v PocketBooku alternativní čtečku (např. velmi populární KOReader) nebo použije vestavěný webový prohlížeč, může se připojit přímo na tvůj server a stahovat knihy ze složky /mnt/data/Knihy bez zapínání počítače či mobilu.

Nasazení Kavity přes Git + Ansible

compose-stacks/kavita/docker-compose.yml

services:
  kavita:
    image: ghcr.io/kareadita/kavita:latest
    container_name: kavita
    environment:
      - PUID=1107  # Unikátní UID vyhrazené pro Kavitu
      - PGID=2000  # Společná skupina media_shared pro přístup na SMB disk
      - TZ=Europe/Prague
    ports:
      - 5000:5000
    volumes:
      - /opt/docker-stacks/kavita/config:/kavita/config
      - "/mnt/data/Knihy:/books"
    restart: unless-stopped

playbooks/servers/Docker-runner/deploy_kavita.yml

---
- name: Nasazení Kavita stacku
  hosts: Docker-runner
  become: true

  tasks:
    - name: Nastavení práv a SGID bitu na složce Knihy na SMB
      ansible.builtin.file:
        path: "/mnt/data/Knihy"
        state: directory
        owner: 1107
        group: 2000
        mode: '2775'

    - name: Vytvoření lokální složky pro compose stack a konfiguraci
      ansible.builtin.file:
        path: ""
        state: directory
        owner: 1107
        group: 2000
        mode: '0775'
      loop:
        - /opt/docker-stacks/kavita
        - /opt/docker-stacks/kavita/config

    - name: Kopírování docker-compose.yml na server
      ansible.builtin.copy:
        src: ../../../compose-stacks/kavita/docker-compose.yml
        dest: /opt/docker-stacks/kavita/docker-compose.yml
        owner: ansible
        group: ansible

    - name: Spuštění kontejneru přes Docker Compose
      community.docker.docker_compose_v2:
        project_src: /opt/docker-stacks/kavita
        state: present

Důležitý chyták při prvním nastavení Kavity!

Až Kavitu spustíte a otevřeš na http://<IP>:5000, dávejte pozor při přidávání knihovny (/books):

  • Nepoužívej soubory přímo v kořeni /mnt/data/Knihy: Kavita z principu ignoruje soubory, které leží přímo v kořenové složce knihovny. Knihy musí být vždy alespoň v jedné podsložce (např. /mnt/data/Knihy/Sapkowski/Zaklinac.epub.
  • Typ knihovny: Při zakládání knihovny vyberte typ Book (pro EPUB/PDF, kde si Kavita bere data přímo z interních metadat souboru) nebo Light Novel (pokud máš v knihách nepořádek v metadatech a chceš, aby se řídila čistě názvy souborů).

V docker-compose.yml jsem nechal namapovaný celý kořen /mnt/data/Knihy:/books. Vytvořil jsem v Kavitě jednu knihovnu „Knihy (CZ)“ namířenou na /books/CZ a druhou „Knihy (EN)“ namířenou na /books/EN. Erika to pak bude mít v prohlížeči i v OPDS katalogu na PocketBooku na první dobrou oddělené a nebude se jí míchat české čtení s cizojazyčným.

SMB mounty

Samotný démon Samby (smbd) naběhne za zlomek vteřiny, ale narážil jsem na souboj dvou různých technologií a jedno chybějící nastavení v /etc/fstab:

Rychlost NVMe vs. rotační disky v ZFS: Virtuálka Docker-runner leží na rychlém systémovém NVMe SSD Samsung a čistý Debian bez GUI nabootuje za 2 až 3 vteřiny. Naproti tomu sdílená složka /data leží na ZFS poolu složeném ze tří 3TB plotnových disků. Roztočení ploten, inicializace HBA/SATA řadiče a zpool import trvá při startu Zalmana klidně 10 až 20 vteřin.

Odložený start a pořadí v Proxmoxu (Start/Shutdown order)

V webovém rozhraní Proxmoxu klikněte na Docker-runner -> Options -> Start/Shutdown order a nastavte:

Start at boot: Yes (zaškrtnuto)

Start/Shutdown order: 2

Startup delay: 15 (nebo 20 sekund)

Parametr Startup delay říká, jak dlouho má Proxmox čekat po nastartování této VM, než spustí další v pořadí. Pokud chcete, aby samotný Docker-runner počkal po startu Zalmana, nastavuje se v Proxmoxu na úrovni uzlu zalman -> System -> Options -> Start on boot delay např. na 15 sekund.