Hitonabi 0935766f61
Ampel / ampel (push) Successful in 28s
feat(uhd): KEYDB.cfg-Unterstuetzung - MakeMKVs Schluessel-Kanal liefert nichts mehr
4K-UHD scheiterte an "The volume key is unknown for this disc". Am 25.07.2026
im Worker-Container nachgemessen: Laufwerk und MakeMKV sind in Ordnung
(LibreDrive v06.3 / Meldung 1011, Disc wird gelesen, AACS-Dump geschrieben) -
MakeMKV versucht gar nicht erst, online einen Schluessel zu holen. Belege:
_private_data.tar enthaelt nur die Index-Datei und KEINE hkd_*.bin; auch mit
geloeschter update.conf (Meldung 5074 belegt den Web-Kontakt) und mit
app_UpdateEnable="1" kam keiner; hkdata.fairuse.org und hkdata.crabdance.com
loesen weltweit nicht mehr auf (NXDOMAIN gegen Fritz!Box, 8.8.8.8, 1.1.1.1).
Betroffen war Akira UHD (MKB v76, Pressung Dez. 2020) - also gerade KEINE
Neuerscheinung. Der bisherige Fehlertext ("Disc neuer als die
Schluessel-Datenbank, mit einem der naechsten Updates rippbar") war falsch.

Einziger heute funktionierender Weg ist eine vom Nutzer selbst mitgebrachte
KEYDB.cfg. Rippy liefert KEINE Schluessel mit, laedt keine herunter und
verteilt keine - es stellt nur den Platz bereit und zeigt an, was dort liegt.

- Datenverzeichnis persistent gemountet (MAKEMKV_DATA_HOST, Default
  /srv/rippy/makemkv): KEYDB.cfg und AACS-Dumps ueberleben jeden Rebuild.
  Vorher loeschte jeder "up -d --build" beides - inklusive des Dumps, auf den
  die Fehlermeldung selbst verwies.
- entrypoint.sh und tasks.py schreiben settings.conf ergaenzend statt
  zerstoerend. Der entrypoint bricht bei nicht beschreibbarem Verzeichnis
  nicht mehr ab - mit "restart: unless-stopped" waere das ein Crashloop
  gewesen, in dem auch reines DVD-Rippen tot ist.
- Neues Zwillings-Modul makemkv_daten.py (docker/api + docker/worker,
  byteweise identisch; test_zwillinge_sind_byteweise_identisch wacht darueber
  und wurde durch absichtliches Verstellen als wirksam nachgewiesen).
- API: GET/POST/DELETE /system/keydb, GET /system/aacs-dumps(/{dateiname}).
  JSON-Body statt Multipart - python-multipart ist bewusst nicht installiert
  und wuerde die API beim Import toeten. nginx client_max_body_size 64m,
  sonst scheitert der Upload mit 413, bevor die API ihn sieht.
- UI (Einstellungen -> System): Status, Hochladen per Datei-Dialog, Entfernen,
  Dump-Download, KEYDB-Plakette je Worker (nur wo das Verzeichnis wirklich
  gemountet ist - ein Remote-Transcode-Worker truege sonst eine Warnung,
  die ihn nichts angeht).
- parse_msg() + log_cb: MakeMKV-Meldungen landen im Rippy-Log (gedrosselt:
  Code 1003 raus, keine Wiederholungen, max. 40 je Rip). Nebenbei behoben:
  der alte Parser (split(",", 4)[3]) schnitt jede Meldung am ersten Komma ab.
- Fuenf Stellen richtiggestellt, die behaupteten, MakeMKV-Updates braechten
  die neueste Disc-Schluessel-Datenbank mit (UI, Anleitung, README,
  Worker-Dockerfile, makemkv_key.py).

NICHT bewiesen: ein erfolgreicher UHD-Rip - es lag keine KEYDB.cfg mit dem
Akira-Schluessel vor. Belegt sind der Befund und die neue Mechanik. So steht
es auch im SAVEPOINT und in der ROADMAP.

Quellen (AGENTS Regel D):
- Datenverzeichnis + Dateiname GROSS/case-sensitiv:
  https://forum.makemkv.com/forum/viewtopic.php?t=30636
- hkd_*.bin in _private_data.tar:
  https://forum.makemkv.com/forum/viewtopic.php?t=32675
- headless settings.conf / app_UpdateEnable:
  https://forum.makemkv.com/forum/viewtopic.php?t=20364
- KEYDB.cfg-Zeilenformat (libaacs):
  https://github.com/ShiftMediaProject/libaacs/blob/master/KEYDB.cfg
- MSG-/PRGV-Format: https://www.makemkv.com/developers/usage.txt

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 01:26:08 +02:00

Rippy — die All-in-one Disc-Ripping-Maschine

Disc rein → automatisch erkannt (Titel, Poster, Metadaten) → verlustfrei gerippt (MakeMKV) → auf Arbeitsgröße komprimiert (HandBrake) → fertig abgelegt, wo DU willst (lokal, NAS, jede Freigabe). Modernes Web-UI, Echtzeit-Fortschritt, komplett in Docker, komplett lokal.

Schnellstart

Voraussetzungen: Docker + Docker Compose, ein optisches Laufwerk am Host.

git clone <repo-url> rippy && cd rippy
cp .env.example .env          # optional: API-Keys — geht auch später im UI
mkdir -p /srv/rippy/media     # Ablage-Basis (anpassbar in docker-compose.yml)
docker compose up -d --build

Dann http://<host> öffnen — der Einrichtungs-Assistent startet beim ersten Mal automatisch (API-Keys, Verarbeitung, erkannte Hardware).

Laufwerk anpassen

Der Worker braucht zwei Host-Geräteknoten: den CD-ROM-Knoten (meist /dev/sr0) und den passenden SCSI-Generic-Knoten (/dev/sgN) — MakeMKV spricht Laufwerke über die sg-Schicht an. Die sg-Nummer ist je Host anders (auf frischen Systemen oft /dev/sg0).

Ermitteln, welche Knoten dein Blu-ray/DVD-Laufwerk hat:

lsscsi -g          # zeigt Modell + zugehörigen /dev/sgN
# oder: ls -la /sys/class/scsi_generic/

Dann in der .env eintragen (Defaults passen für den Ursprungs-Host):

OPTICAL_SR=/dev/sr0    # CD-ROM-Knoten deines Laufwerks
OPTICAL_SG=/dev/sg0    # sg-Knoten deines Laufwerks

docker compose up -d nutzt diese Werte. (Für Feineinstellungen geht weiterhin eine docker-compose.override.yml mit eigenen devices:-Einträgen.)

Laufwerk in einer VM? Per USB-Passthrough anhand der Vendor-ID durchreichen (Proxmox: qm set <vmid> -usb0 host=xxxx:yyyy,usb3=1) — NICHT als emuliertes CD-ROM (media=cdrom), das kann keine SCSI-Kommandos.

Wie es funktioniert

  1. Disc-Wache (ioctl-Polling, kein udev-Gefrickel) erkennt Einlegen, identifiziert die Disc (Volume-Label → TMDB → OMDb-Fallback) und zeigt sie mit Poster auf dem Dashboard. Klick auf einen Job-Titel öffnet die Detail-Ansicht (Poster, Jahr, Beschreibung, Ablagepfad).
  2. Rip (MakeMKV, verlustfrei — der einzige Weg durch AACS): Ziel wählst du beim Start (Filme/Serien/Musik/eigener Pfad, inkl. Netzwerk-Ziele) — oder du stellst die Vollautomatik an (Einstellungen → Ripping) und der Rip startet ohne Nachfrage in den passenden Schnellwahl-Ordner. Optional nur Hauptfilm (längster Titel, Extras bleiben weg). Bereits gerippte Discs erkennt Rippy am Fingerabdruck und warnt. Vor dem Start prüft Rippy den freien Platz gegen die Disc-Größe. Alle Tonspuren und Untertitel bleiben erhalten (wichtig für Anime/O-Ton). Audio-CDs laufen über abcde → FLAC + MusicBrainz. Serien: Im Dialog „Serien" wählen → Serienname + Staffel angeben — Ablage wird <Serie>/Season NN, und die Episoden werden nach dem Rip per Laufzeitabgleich (TMDB) automatisch zu „Serie S01E02.mkv" benannt (nur bei eindeutiger Zuordnung — sonst bleiben die Namen, mit Log).
  3. Kompression (HandBrake, eigener Job auf eigener Queue): x265/x264, Preset im UI wählbar; Rohdatei wird erst nach Erfolg gelöscht („Original behalten" als Option). Fehlgeschlagene Kompressionen lassen sich ohne Neu-Rip neu anstoßen.
  4. Media-Server-Ablage: Unter Einstellungen → Ripping (oder im Einrichtungs-Assistenten) wählst du dein System — Jellyfin, Emby, Kodi, Plex oder keins. Fertige Rips heißen dann „Titel (Jahr)" statt Job-UUID; für Jellyfin/Emby/Kodi legt Rippy zusätzlich movie.nfo + poster.jpg dazu (Kodi-NFO-Schema, lesen alle drei nativ). Plex nutzt nur die Benennung. Jellyfin/Emby: Server-URL + API-Key eintragen, dann stößt Rippy nach jedem fertigen Rip sofort einen Bibliotheks-Scan an — Disc rein, Film erscheint im Server.
  5. 4K-UHD: braucht zwei Dinge — ein LibreDrive-fähiges Laufwerk (MakeMKV-Forum: „Ultimate UHD Drives Flashing Guide") und einen passenden Disc-Schlüssel. Normale BD/DVD gehen mit jedem Laufwerk und ohne Schlüssel-Datei. Der Schlüssel ist heute die eigentliche Hürde. Am 25.07.2026 auf der Rippy-VM gemessen (Akira UHD, MKB v76, Pressung Dezember 2020): Laufwerk und MakeMKV waren in Ordnung — „Using LibreDrive mode (v06.3)", die Disc wurde gelesen — und trotzdem kam „The volume key is unknown for this disc". MakeMKV versucht dabei gar nicht mehr, online einen Schlüssel zu holen, und die früher genutzten Schlüssel-Server (hkdata.fairuse.org, hkdata.crabdance.com) lösen weltweit nicht mehr auf. Ein MakeMKV-Update ändert daran nichts. Der einzige Weg, der heute funktioniert, ist eine Datei KEYDB.cfg (GROSS geschrieben — Linux unterscheidet Groß- und Kleinschreibung) im MakeMKV-Datenverzeichnis. Die legst du unter Einstellungen → System ab (siehe unten). ⚠️ Rippy liefert keine Schlüssel mit, lädt keine herunter und verteilt keine. Rippy stellt nur den Platz für eine Datei bereit, die du selbst mitbringst, und zeigt dir ehrlich an, was dort liegt. ⚠️ UHD-Rohdaten sind bis 100 GB groß — wenn die Platte der Rippy-Maschine dafür zu klein ist, lege das Arbeitsverzeichnis (Einstellungen → Verarbeitung) auf eine eingehängte Freigabe, z. B. /app/media/nas-arbeit. Rippy bricht sonst VOR dem Rip mit einer Klartext-Meldung ab statt nach 40 GB mit voller Platte.

Speicherziele (NAS, Freigaben)

Unter Einstellungen → Speicherziele hängst du NFS- oder SMB-Freigaben direkt aus dem UI ein — sie erscheinen sofort in der Ziel-Auswahl beim Rippen und werden beim Start automatisch wieder verbunden. Technik: der api-Container läuft mit CAP_SYS_ADMIN und einem rshared-Bind auf /srv/rippy/media, Mounts propagieren zu allen Containern. ⚠️ Zugangsdaten liegen unverschlüsselt in der lokalen Postgres-DB — bewusster Heimnetz-Kompromiss; lege fürs NAS einen eigenen, eingeschränkten Benutzer an.

Benachrichtigungen

Einstellungen → Benachrichtigungen: eine Webhook-URL eintragen, „Test senden" drücken, speichern — fertig. Rippy meldet Job-Ende (fertig, fehlgeschlagen, abgebrochen) und erkennt den Dienst an der URL selbst:

Dienst URL-Beispiel Format
Discord https://discord.com/api/webhooks/… {"content": …}
Slack https://hooks.slack.com/services/… {"text": …}
ntfy (Handy-Push) https://ntfy.sh/mein-geheimes-thema Roh-Text + Titel
Eigenes (HA, n8n, …) beliebige HTTPS-URL {"title","message","level"}

System, MakeMKV-Beta-Key, Disc-Schlüssel & Updates

Einstellungen → System zeigt die Werkzeug-Versionen jedes Workers (MakeMKV, HandBrake), den Key-Status und den freien Speicherplatz. Der MakeMKV-Beta-Key (wechselt ~monatlich, Forum-Thread t=1053) wird hier im UI eingetragen und gilt ab dem nächsten Rip — ohne Rebuild, ohne Neustart; er schlägt den Key aus der .env.

Disc-Schlüssel (KEYDB.cfg) — im selben Tab, nur für 4K-UHD nötig:

  • Status: Rippy zeigt, ob eine KEYDB.cfg im MakeMKV-Datenverzeichnis liegt, mit Pfad, Größe, Anzahl der Disc-Einträge und Änderungsdatum.
  • Hochladen: Knopf „KEYDB.cfg hochladen", dann deine eigene Datei im Datei-Dialog auswählen — mehr ist nicht zu tun. Rippy prüft den Inhalt auf Plausibilität und lehnt Unsinn (leere Datei, versehentlich geladene HTML-Fehlerseite) mit einer deutschen Klartext-Meldung ab, statt ihn stillschweigend zu speichern.
  • Entfernen: ein Knopf, die Datei ist wieder weg.
  • AACS-Dumps herunterladen: MakeMKV legt bei jeder unbekannten Disc selbst einen Dump ab. Genau den braucht man, wenn man im MakeMKV-Forum um den Schlüssel für eine neue Pressung bittet — hier holst du ihn dir aus dem Container, ohne SSH.

Der Beta-Key ist die Lizenz für die Software; die KEYDB.cfg sind Disc-Schlüssel — zwei völlig verschiedene Dinge. Rippy liefert und lädt keine Disc-Schlüssel, es hält nur ein persistentes Verzeichnis dafür bereit (MAKEMKV_DATA_HOST, siehe Tabelle unten) — rebuild-fest, damit deine Datei einen docker compose build überlebt.

Updates: „Auf Updates prüfen" vergleicht mit makemkv.com und den offiziellen HandBrake-Releases (12 h gecacht). MakeMKV-Update ohne Code-Änderung: MAKEMKV_VERSION=x.y.z in die .env, dann docker compose build worker && docker compose up -d worker. ⚠️ Richtigstellung (25.07.2026): Hier stand früher, neue MakeMKV- Versionen brächten „auch die neueste Disc-Schlüssel-Datenbank mit". Das ist widerlegt — auf der VM nachgemessen: MakeMKV holt für eine unbekannte UHD-Disc keinen Schlüssel mehr, weder mitgeliefert noch aus dem Netz. Ein Update lohnt für Programmfehler und neue Laufwerke, hilft aber NICHT gegen „The volume key is unknown". Dafür brauchst du die KEYDB.cfg. HandBrake kommt im Docker-Worker bewusst aus Debian (stabil, hinkt der offiziellen Version hinterher); der native Windows-Worker nutzt die aktuelle Version direkt.

Verarbeitung & Hardware

Einstellungen → Verarbeitung zeigt ehrlich an, welche Encoder deine Worker WIRKLICH haben (CPU x264/x265, VAAPI bei AMD/Intel-GPU, NVENC bei NVIDIA) — jeder Worker meldet seine Fähigkeiten selbst beim Start.

Optional: weitere Maschinen als Transcode-Worker

Die Kompression läuft als eigener Celery-Task auf der Queue transcode — JEDE Maschine im Netz kann sie übernehmen. Einstellungen → Worker zeigt für beide Varianten einen Copy-Paste-Befehl:

  • Linux (Docker): deploy/remote-transcode-worker.yml
  • Windows (nativ, ohne Docker): braucht nur Python 3.10+ — der Installer (install.ps1) kommt von der Rippy-Instanz selbst (/api/worker-setup/windows), lädt Worker-Code und HandBrakeCLI automatisch und erzeugt eine start-worker.bat (optional -Autostart).

Ohne Zusatz-Worker macht der eingebaute CPU-Worker alles selbst — Rippy bleibt All-in-one.

Umgebungsvariablen (.env)

Variable Pflicht Zweck
TMDB_API_KEY empfohlen Metadaten (deutsche Texte) — alternativ im UI/Wizard; beide Key-Arten gehen (v3-Schlüssel und v4-Token)
WORKER_NAME optional Anzeigename des eingebauten Workers (Standard: rippy-hauptworker)
OMDB_API_KEY optional zweite Metadaten-Quelle (Fallback)
THETVDB_API_KEY optional Serien-Fallback
MAKEMKV_APP_KEY optional MakeMKV-Beta-Key (Forum); DVDs gehen ohne — bequemer: im UI unter Einstellungen → System pflegen
MAKEMKV_URL_BASE optional alternative Download-Quelle für den Image-Build
MAKEMKV_DATA_HOST optional Host-Verzeichnis für MakeMKVs Daten (Default /srv/rippy/makemkv) — hier liegen deine KEYDB.cfg und die AACS-Dumps; persistent, überlebt jeden Rebuild
OPTICAL_SR je Host Host-Pfad des CD-ROM-Knotens (Default /dev/sr0) — siehe „Laufwerk anpassen"
OPTICAL_SG je Host Host-Pfad des sg-Knotens des Laufwerks (Default /dev/sg1; oft /dev/sg0)
POSTGRES_PASSWORD optional DB-Passwort (Default rippy) — für exponierte Umgebungen ein starkes Passwort setzen

UI-Einstellungen (Wizard/Settings) überstimmen die Env-Variablen.

Rippy woanders bereitstellen

Rippy ist reines Docker Compose — es läuft auf jedem Linux-Host mit Docker, nicht nur auf der Original-VM. Es gibt (noch) keine fertigen Registry-Images; gebaut wird beim ersten up direkt aus dem Repo.

Voraussetzungen auf dem Ziel-Host:

  1. Linux (x86_64) mit Docker + Compose-Plugin.
  2. Ein optisches Laufwerk, das der Host sieht (ls /dev/sr* /dev/sg*). In einer VM: per USB-Passthrough (Vendor-ID) durchreichen, NICHT als emuliertes CD-ROM — siehe „Laufwerk anpassen" oben.
  3. Ablage-Basis anlegen: mkdir -p /srv/rippy/media (oder Pfad in docker-compose.yml anpassen). Der Bind nutzt shared/slave-Propagation (fürs In-UI-Einhängen von NAS-Freigaben). Auf den meisten systemd-Linux-Hosts ist / schon rshared, dann ist nichts zu tun. Bricht docker compose up mit „path … is mounted on / but it is not a shared mount" ab, einmalig:
    sudo mount --bind /srv/rippy/media /srv/rippy/media
    sudo mount --make-rshared /srv/rippy/media
    
    (reboot-fest als systemd-.mount-Unit persistieren.) Braucht einen klassischen Linux-Docker-Host mit SYS_ADMIN — nicht Docker-Desktop/rootless/Podman.
  4. MakeMKV-Datenverzeichnis anlegen: mkdir -p /srv/rippy/makemkv (oder eigenen Pfad über MAKEMKV_DATA_HOST in der .env). Dort liegen MakeMKVs Programmzustand, die AACS-Dumps und — falls du 4K-UHD rippst — deine eigene KEYDB.cfg. Das Verzeichnis gehört dem Host, damit ein docker compose build deine Datei nicht wegwirft.

Dann wie im Schnellstart: klonen, .env füllen, docker compose up -d --build, http://<host> öffnen — der Einrichtungs-Assistent führt durch den Rest (API-Keys, Media-Server, Verarbeitung). Updates: git pull && docker compose up -d --build.

Nicht mitnehmen musst du: Gitea, Arcane, den CI-Runner — das ist die Entwicklungs-Infrastruktur DIESER Installation, nicht Teil von Rippy.

Härtung für fremde/exponierte Netze

Rippy ist bewusst Heimnetz-only: Es hat keine Authentifizierung, und Redis + PostgreSQL veröffentlichen Ports auf allen Interfaces (für Remote-Worker). Im vertrauten LAN ist das ein akzeptierter Kompromiss — exponiere Rippy niemals ungeschützt an ein unsicheres oder öffentliches Netz. Wer es weiter absichern will:

  • Zugriff kapseln: API (:8000) und UI hinter einen Reverse-Proxy mit Auth (Basic-/Forward-Auth) legen oder nur über VPN erreichbar machen; Port 8000 nicht auf 0.0.0.0 binden.
  • DB/Broker abschotten: POSTGRES_PASSWORD in der .env auf ein starkes Passwort setzen; die Ports 5432/6379 nur an ein internes/VPN-Interface binden (z. B. "10.0.0.5:5432:5432") statt an 0.0.0.0; Redis mit --requirepass <geheim> starten und das Passwort in REDIS_URL ergänzen.
  • CORS: main.py erlaubt aktuell * (nötig, weil UI und API getrennte Ports sind) — hinter einem Proxy auf die echte UI-Herkunft einschränken.
  • NAS-Zugangsdaten liegen bewusst im Klartext in der DB — ein weiterer Grund, den DB-Port nie offen ins unsichere Netz zu hängen.

Entwicklung

CI („Ampel") läuft bei jedem Push: Ruff, pytest, Vite-Build. Es gibt genau einen Branch, main (Single Source of Truth) — die Ampel prüft nur, deployt wird direkt aus main. Rot heißt: nicht deployen. Regeln für Beiträge: AGENTS.md · Konzept: KONZEPT.md · Fahrplan: ROADMAP.md

S
Description
Modernes automatisches CD/DVD/Blu-ray-Ripping-System mit WebUI und Proxmox-Integration
Readme 418 MiB
Languages
Python 63.7%
TypeScript 32.5%
Shell 2.5%
Dockerfile 1%
CSS 0.2%