Audiobookshelf
⏳ Doba čtení: ~6 min (843 slov)Nasazení Audiobookshelf v Proxmox homelabu přes Ansible
Když člověk staví homelab, dříve nebo později narazí na zásadní křižovatku: buď bude služby na serveru klikat a lepit ručně v terminálu, nebo k tomu přistoupí jako k produkční infrastruktuře. Rozhodl jsem se proto jít cestou Infrastructure as Code (IaC) a celý stack Audiobookshelf nasadit přes Ansible.
Zde je architektonický výcuc toho, co a proč jsme poskládali, včetně všech slepých uliček, kterým se můžete vyhnout.
Architektura: Čistý hypervizor a dedikovaný Docker-runner
Základní sysadmin pravidlo pro Proxmox zní: udržuj samotný hypervizor co nejčistší. Místo abychom instalovali Docker přímo do železa, postavili jsme pro aplikační kontejnery dedikovaný virtuální stroj (Docker-runner):
- Základ: Bezobslužná instalace čistého Debianu bez GUI pomocí vlastního upraveného preseed ISO obrazu.
- Přístup: Preseed rovnou vytvoří servisního uživatele
ansiblese zablokovaným heslem, vloží mu SSH klíč a nastaví bezheslovésudo. - Výsledek: Po nabootování VM máme během pár minut čisté plátno připravené na to, aby ho plně převzal Ansible z lokálního počítače.
Bezpečnost na prvním místě: SMB, Least Privilege a UID/GID
Moje sbírka audioknih leží na síťovém SMB disku přímo na Zalmanovi (//192.168.1.100/data). Cílem bylo:
- Zachovat přímý přístup k souborům přes běžnou síťovou složku z Windows/Linuxu.
- Nedovolit kontejneru s Audiobookshelfem, aby viděl zbytek disku (fotky, zálohy, instalačky).
- Dodržet princip nejnižších privilegií (Principle of Least Privilege) – tedy žádný kontejner běžící pod
rootemnebo jedním globálním uživatelem.
[!note] Do budoucna plánuji samostatnou virtuálku na které poběží jen SMB server, aby byla oddělena od Proxmox hypervizoru a dalších služeb.
Jak jsem to vyřešil:
-
Unikátní UID + Společné GID: Vytvořil jsem na hostiteli sdílenou skupinu
media_shareds pevně daným GID2000. Samotný kontejner Audiobookshelf dostal své vlastní unikátní UID1106a běží pod skupinou2000. Pokud by někdo kontejner kompromitoval, nedostane se ke konfiguracím ostatních služeb. - Selektivní Bind Mounts: Celý SMB share se přes Ansible roli a Ansible Vault (pro šifrování hesel v Gitu) připojí na
Docker-runnerdo/mnt/datas právy nastavenými pro skupinumedia_shared. Do samotného Docker kontejneru ale nepropisujeme celý disk – namapujeme mu přes volumes exkluzivně jen podsložky/mnt/data/Audio knihya/mnt/data/Podcasts. O existenci okolních složek nemá kontejner ani tušení. - SGID bit: Složkám jsem v Ansible nastavil práva
2775(SGID), což zaručuje, že jakýkoliv nově vytvořený soubor automaticky zdědí skupinu2000a ostatní služby s ním nebudou mít problém pracovat.
Peklo s balíčky v čistém Debianu (docker.io vs. docker-ce)
Výchozí repozitáře Debianu obsahují starší balíčky docker.io a docker-compose, které vůbec neobsahují moderní plugin docker-compose-plugin (Compose V2). Když jsme následně přes vlastní Ansible roli přidali oficiální repozitář Dockeru (ve formátu deb822), instalace havarovala na konfliktu v dpkg, protože nový docker-compose-plugin se snažil přepsat binárku ze starého balíčku docker-compose.
Řešení: Na čistý Debian nikdy neinstalujte Docker z výchozích distribučních repozitářů. Rovnou přidejte oficiální Docker repozitář a instalujte sadu docker-ce, docker-ce-cli, containerd.io a docker-compose-plugin.
Výsledný stav a struktura v Gitu
Nyní celý stack nahodíme (nebo po případné katastrofě kompletně obnovíme na novém stroji) jediným příkazem ansible-playbook.
Finální výsek z docker-compose.yml, který Ansible na server doručí a spustí, vypadá takto:
services:
audiobookshelf:
image: ghcr.io/advplyr/audiobookshelf:latest
container_name: audiobookshelf
environment:
- PUID=1106 # Unikátní UID vyhrazené pro Audiobookshelf
- PGID=2000 # Společná skupina media_shared pro přístup na SMB disk
- TZ=Europe/Prague
ports:
- 13378:80
volumes:
- /opt/docker-stacks/audiobookshelf/config:/config
- /opt/docker-stacks/audiobookshelf/metadata:/metadata
- "/mnt/data/Audio knihy:/audiobooks"
- "/mnt/data/Podcasts:/podcasts"
restart: unless-stopped
(Poznámka: Konfiguraci a metadata držíme přímo na rychlém lokálním NVMe disku virtuálky v /opt, zatímco těžká média si kontejner tahá přes síť ze Samby).
Teď už Audiobookshelf spokojeně běží na portu 13378, indexuje stávající knihovnu a já mám v Gitu připravenou šablonu, podle které v dalších krocích úplně stejně nasadím zbytek mediálního stacku.
Reference
Použil jsem:
- Ansible suite - Hynkovu organizaci pro Ansible role a playbooky
- Ansible site - repo s konfigurací pro Ansible
- Ansible Role: smb_mounts - role pro připojení SMB disků
- Ansible Role: apt_thirdparty - role pro přidání repozitářů třetích stran (např. Docker)
- Moje homelab repo - Můj vlastní repozitář s Ansible playbooky pro homelab
- Audiobookshelf