# Docker Compose für Rippy # # Geräte-Zugriff (22.07./23.07.-Lehre): Optische Laufwerke MÜSSEN als devices: # eingebunden werden. Bind-Mounts unter volumes: geben dem Container zwar den # Geräteknoten, aber KEINE Berechtigung im Device-Cgroup → jedes open() scheitert # mit EPERM. Voraussetzung: Die VM sieht das Laufwerk (USB-Passthrough auf pve). services: api: build: context: . dockerfile: docker/api/Dockerfile environment: - DATABASE_URL=postgresql://rippy:${POSTGRES_PASSWORD:-rippy}@postgres:5432/rippy - REDIS_URL=redis://redis:6379/0 - TMDB_API_KEY=${TMDB_API_KEY:-} - THETVDB_API_KEY=${THETVDB_API_KEY:-} - OMDB_API_KEY=${OMDB_API_KEY:-} # Dasselbe Host-Verzeichnis wie beim Worker, nur an neutraler Stelle: # die API liest den KEYDB-Status und die AACS-Dumps und nimmt eine # hochgeladene KEYDB.cfg entgegen (Einstellungen → System). - MAKEMKV_DATA_DIR=/app/makemkv-data - LOG_LEVEL=INFO healthcheck: test: ["CMD-SHELL", "python -c 'import urllib.request; urllib.request.urlopen(\"http://localhost:8000/health\")'"] interval: 30s timeout: 10s retries: 3 start_period: 10s ports: - "8000:8000" # SYS_ADMIN: die API hängt Netzwerk-Speicherziele (NFS/SMB) selbst ein # (mounts.py) — dank rshared-Propagation unten sehen Host UND Worker # jeden Mount sofort. # DAC_READ_SEARCH: mount.cifs hebt diese Capability an (toggle_dac_ # capability) — sie fehlt in Dockers Default-Set, ohne sie stirbt JEDER # SMB-Mount mit "Unable to apply new capability set" (Befund 24.07., # auf der VM reproduziert und mit dieser Capability bewiesen behoben). cap_add: - SYS_ADMIN - DAC_READ_SEARCH security_opt: - apparmor:unconfined volumes: # /srv/rippy/media auf der VM statt anonymem Volume: rshared lässt # Mounts aus DIESEM Container zum Host und in andere Container # propagieren (Commander-Anforderung 23.07.: Ziele frei wählbar). - type: bind source: /srv/rippy/media target: /app/media bind: propagation: rshared - temp:/app/temp # MakeMKV-Datenverzeichnis (dasselbe wie im Worker, siehe dort). - ${MAKEMKV_DATA_HOST:-/srv/rippy/makemkv}:/app/makemkv-data devices: - ${OPTICAL_SR:-/dev/sr0}:/dev/sr0 networks: - rippy-net depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped read_only: false worker: build: context: . dockerfile: docker/worker/Dockerfile args: # Übersteuerbar via .env — makemkv.com ist zeitweise down (Cloudflare # 525); dann Wayback-Snapshot als MAKEMKV_URL_BASE eintragen. # /download = aktuelle Version, /download/old = ältere Versionen. MAKEMKV_URL_BASE: ${MAKEMKV_URL_BASE:-https://www.makemkv.com/download} # MakeMKV-Update OHNE Code-Änderung: neue Version in die .env, # Tarballs nach docker/worker/vendor/ legen (oder Download klappt), # dann docker compose build worker && docker compose up -d worker. # Einstellungen → System meldet, wenn es eine neuere Version gibt. MAKEMKV_VERSION: ${MAKEMKV_VERSION:-1.18.4} environment: - DATABASE_URL=postgresql://rippy:${POSTGRES_PASSWORD:-rippy}@postgres:5432/rippy - REDIS_URL=redis://redis:6379/0 - RIP_OUTPUT_DIR=/app/media - MAKEMKV_APP_KEY=${MAKEMKV_APP_KEY} # MakeMKVs Datenverzeichnis im Container — fest verdrahtet in MakeMKV # selbst (HOME/.MakeMKV, HOME ist /root). Steht hier, damit Worker-Code # und Mount dieselbe Wahrheit benutzen. - MAKEMKV_DATA_DIR=/root/.MakeMKV # Anzeigename in Einstellungen → Worker (stabil über Rebuilds hinweg; # via .env übersteuerbar, z. B. WORKER_NAME=wohnzimmer-vm) - WORKER_NAME=${WORKER_NAME:-rippy-hauptworker} # Für Serien-Episoden-Matching: der Worker fragt die API nach den # Episoden-Laufzeiten der Staffel (TMDB). - API_URL=http://api:8000 - LOG_LEVEL=INFO volumes: - type: bind source: /srv/rippy/media target: /app/media bind: propagation: rslave - temp:/app/temp # MakeMKV-Datenverzeichnis PERSISTENT (Befund 25.07.2026, live gemessen): # Hier liegen die KEYDB.cfg — heute die EINZIGE funktionierende # Schlüsselquelle für 4K-UHD, weil MakeMKVs Online-Kanal nichts mehr # liefert —, die AACS-Dumps fehlgeschlagener Discs und settings.conf. # Ohne diesen Mount löschte JEDER `up -d --build` beides; die # Fehlermeldung schickte den Nutzer zu einer Datei, die es nicht mehr gab. - ${MAKEMKV_DATA_HOST:-/srv/rippy/makemkv}:/root/.MakeMKV devices: # Host-Geräteknoten via .env (OPTICAL_SR/OPTICAL_SG) — je Rechner ANDERS! # MakeMKV spricht Laufwerke über die SCSI-Generic-Schicht an; ohne den # passenden sg-Knoten findet es „keine usable optical drives". Den sg-Knoten # des Laufwerks auf DIESEM Host ermitteln (lsscsi -g) und in die .env eintragen. # Achtung: nach USB-Reconnect zur Laufzeit kann die sg-Nummer wandern → # Container neu starten. Defaults (sr0/sg1) passen für den Ursprungs-Host. - ${OPTICAL_SR:-/dev/sr0}:/dev/sr0 - ${OPTICAL_SG:-/dev/sg1}:/dev/sg1 networks: - rippy-net depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped # read_only bleibt Ziel (Etappe 6), aber MakeMKV/abcde brauchen HOME + # Settings — bis zur Härtung schreibbar, Ausgabe geht ohnehin aufs Volume. read_only: false tmpfs: - /app/tmp - /run - /tmp ui: build: context: . dockerfile: docker/ui/Dockerfile ports: - "80:80" networks: - rippy-net depends_on: - api restart: unless-stopped postgres: image: postgres:16-alpine environment: - POSTGRES_USER=rippy - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-rippy} - POSTGRES_DB=rippy # Veröffentlicht (Befund 24.07.): Remote-Worker (GPU-Maschine, künftiger # Windows-Worker) verbinden sich über :5432/6379 — ohne # ports: konnte sich NIE ein Remote-Worker anbinden. Heimnetz-Kompromiss, # wie die Klartext-Credentials (README). ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data networks: - rippy-net restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U rippy -d rippy"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine # Siehe postgres: Pflicht für Remote-Worker (Celery-Broker). ports: - "6379:6379" volumes: - redis-data:/data networks: - rippy-net restart: unless-stopped command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: rippy-net: driver: bridge volumes: temp: postgres-data: redis-data: