# Flaro auf dem NAS einrichten Für ein UGREEN-NAS mit der mitgelieferten Docker-App, und für jedes andere System, auf dem Docker Compose läuft. ## Die kurze Antwort auf „ein Image oder mehrere?" **Ein einziges.** Die Weboberfläche wird beim Bauen mit hineingelegt und vom Server selbst ausgeliefert; es gibt keinen zweiten Container, keine Datenbank daneben, keinen Proxy davor. Ein Container, drei Volumes, fertig. ``` flaro: 231 MB ├── .NET-Laufzeit + Flaro ├── wwwroot/ die Weboberfläche └── ffmpeg + VAAPI-Treiber ``` --- ## Schritt 1: Die Architektur bestimmen **Das ist der Schritt, den man am leichtesten überspringt und am teuersten bezahlt.** Ein Image für `arm64` läuft auf einem Intel-NAS nicht, und die Fehlermeldung (`exec format error`) sagt das nicht deutlich. Auf dem NAS, über SSH oder die Konsole der Docker-App: ```bash uname -m ``` | Ausgabe | Architektur | Was du bauen musst | |---|---|---| | `x86_64` | amd64 | `--platform linux/amd64` | | `aarch64` | arm64 | `--platform linux/arm64` | Die meisten UGREEN-Geräte mit Intel-Prozessor (N100, i5) melden `x86_64`. Ein Mac baut ohne Angabe **arm64** — also gehört die Angabe dazu. --- ## Schritt 2: Das Image auf das NAS bringen **Das NAS baut nicht, es lädt nur.** Genau wie bei Jellyfin oder jedem anderen Container: dort baut jemand anderes und veröffentlicht, du ziehst das Ergebnis. Bei Flaro ist dieser Jemand dein Arbeitsrechner — er ist für die Apps ohnehin nötig, weil Xcode nirgendwo sonst läuft. Drei Wege. Der erste ist der vorgesehene; der zweite braucht keine Registry. ### Weg A — über die Registry deines Gitea (empfohlen) Dein Gitea unter `git.scarriffle.com` bringt eine Container-Registry mit. Einmal einrichten, danach ist jedes Update ein `docker compose pull`. #### A1 · Anmelden, einmalig Nicht mit dem Kontopasswort, sondern mit einem Zugriffstoken: *Gitea → Einstellungen → Anwendungen → Zugriffstoken*, Berechtigungen `write:package` und `read:package`. Ein Token lässt sich einzeln widerrufen, und bei eingeschalteter Zwei-Faktor-Anmeldung funktioniert das Passwort hier gar nicht. ```bash docker login git.scarriffle.com ``` Benutzername ist dein Gitea-Name, als Passwort das Token. #### A2 · Bauen und hochladen Ein Befehl; er baut amd64 **und** arm64 und lädt beides als ein Manifest hoch: ```bash Tools/image-veroeffentlichen.sh ``` Mit einer Fassungsnummer, wenn du sie festnageln willst: ```bash Tools/image-veroeffentlichen.sh 0.2.0 ``` Nur die Architektur des NAS — deutlich schneller, weil die fremde sonst unter Emulation gebaut wird: ```bash FLARO_PLATTFORMEN=linux/amd64 Tools/image-veroeffentlichen.sh ``` #### A3 · Das Paket öffentlich stellen Sonst muss sich auch das NAS anmelden. In Gitea unter *dein Profil → Pakete → flaro → Einstellungen* auf öffentlich stellen. Der Quelltext ist ohnehin offen; das Image enthält nichts, was er nicht auch enthält. #### A4 · Die Registry im NAS eintragen In der Docker-App des UGREEN: **Repository → Zahnrad → Quellname des Images → Hinzufügen**. Dort stehen schon DockerHub und `ghcr.io`; daneben kommt: | Feld | Wert | |---|---| | Alias | `gitea` | | Link | `https://git.scarriffle.com/` | **Bestätigen** — danach findet die Suche in der Docker-App auch `scarriffle/flaro`. Ist das Paket privat, trägst du unter *Registierungseinstellungen* Benutzername und dasselbe Zugriffstoken ein. #### A5 · Das Image herunterladen, bevor du das Projekt anlegst **Die Docker-App zieht Images nicht selbst.** Steht in einer Compose-Datei ein Image, das lokal fehlt, bricht sie das Anlegen mit „Bitte überprüfen Sie die Konfigurationsinformationen" ab — ohne zu sagen, woran es liegt. Also vorher **Image → Herunterladen**, Registry `gitea`, Quellname `scarriffle/flaro:latest`. In der Compose-Datei steht dann: ```yaml image: git.scarriffle.com/scarriffle/flaro:latest ``` ### Weg B — als Datei hochladen Ohne Registry, dafür bei jedem Update von Hand. ```bash docker buildx build --platform linux/amd64 \ -f server/Dockerfile -t flaro:latest --load . ``` ```bash docker save flaro:latest | gzip > flaro.tar.gz ``` Das ergibt rund **230 MB** — gemessen, nicht geschätzt. Das `gzip` bringt dabei fast nichts: die Ebenen eines Docker-Images sind bereits gepackt. Die Datei über die Dateiverwaltung auf das NAS legen, dann dort: ```bash docker load < /volume1/docker/flaro.tar.gz ``` In der Compose-Datei steht dann schlicht `image: flaro:latest`. ### Weg C — Gitea baut selbst `.gitea/workflows/image.yml` liegt im Projekt und kann denselben Bau auf einem Act-Runner ausführen. **Gitea verteilt Arbeit nur, es baut nicht selbst** — ohne registrierten Runner passiert nichts. Der Runner müsste auf dem NAS laufen, und daran scheitert es dort: er braucht Zugriff auf Docker, denn sein Zweck ist das Bauen von Images. Die Docker-App des UGREEN lehnt den Einhängepunkt `/var/run/docker.sock` ab — geprüft, indem die Compose-Datei Zeile für Zeile aufgebaut wurde: ohne diese eine Zeile wird das Projekt angelegt, mit ihr nicht. Übrig bleiben `privileged: true` mit einem Docker-in-Docker-Image oder der Weg über SSH an der Oberfläche vorbei. Beide geben dem Runner faktisch Root auf dem NAS. Deshalb löst der Workflow **nicht** mehr bei jedem Push aus — sonst sammeln sich Läufe an, die nie jemand abarbeitet. Er steht auf `workflow_dispatch` und lässt sich in Gitea von Hand starten, sobald einmal ein Runner da ist. --- ## Schritt 3: Die Compose-Datei ```yaml services: flaro: image: git.scarriffle.com/scarriffle/flaro:latest container_name: flaro restart: unless-stopped ports: - "8096:8080" environment: - TZ=Europe/Zurich # Schreibt Plakate und NFO neben die Mediendateien. Ohne das bleibt # der Medienordner unangetastet. - FLARO_WRITE_SIDECARS=true volumes: # Datenbank und Konfiguration. **Das ist das Volume, das du sichern # musst** — darin stehen Benutzer, Zuordnungen und Sehfortschritt. - /volume1/docker/flaro/config:/config # Heruntergeladene Plakate. Verlierbar: wird neu geholt. - /volume1/docker/flaro/cache:/cache # Umgepackte Dateien. Ebenfalls verlierbar, kann aber gross werden. - /volume1/docker/flaro/transcode:/transcode # Die Medien. Links der Pfad auf dem NAS, rechts der im Container — # und **rechts** ist der, den du in Flaro einträgst. - /volume1/Medien/Filme:/media/Filme - /volume1/Medien/Serien:/media/Serien # Hardware-Beschleunigung. Weglassen, wenn das NAS keine hat. devices: - /dev/dri:/dev/dri ``` ### Rechte Der Container läuft als Benutzer `1000:1000` — der erste Benutzer auf fast jedem Linux und auf den üblichen NAS-Geräten. Gehören deine Ordner jemand anderem, setz es ausdrücklich: ```yaml user: "1001:100" ``` Welche Kennung gilt, sagt auf dem NAS: ```bash id ``` ### Der Port `8096` ist frei gewählt. Läuft dort schon Jellyfin, nimm etwas anderes — links die Zahl, unter der du Flaro erreichst, rechts bleibt `8080`. --- ## Schritt 4: Starten und einrichten ```bash docker compose up -d ``` Dann im Browser `http://:8096` öffnen. Es erscheint der Einrichtungsassistent: 1. **Administratorkonto** anlegen — Benutzername und Passwort, mindestens acht Zeichen. 2. Unter **Verwaltung → Mediatheken** eine Mediathek hinzufügen. Beim Ordner gehört der Pfad **im Container** hinein, also `/media/Filme`, nicht `/volume1/Medien/Filme`. 3. **Scannen.** Der Scan liest die Dateien, danach holt Flaro die Metadaten. 4. Unter **Verwaltung → Server → Metadaten** die Sprache einstellen, etwa `de-DE`. Danach einmal **Metadaten auffrischen** — vorhandene Titel ändern sich sonst nicht. --- ## Sichern Was unersetzlich ist, liegt in **einem** Verzeichnis: ``` /volume1/docker/flaro/config/ ``` Darin: die SQLite-Datenbank mit Benutzern, Zuordnungen, Sehfortschritt und Einstellungen. Eine Kopie dieser Datei ist die ganze Sicherung — kein Datenbank-Dump, kein Export. `cache` und `transcode` dürfen weg; beides baut sich neu auf. **Die Mediendateien fasst Flaro nicht an.** Es liest sie, und es legt — sofern `FLARO_WRITE_SIDECARS=true` gesetzt ist — Plakate und NFO-Dateien daneben. Umbenannt oder gelöscht wird nie etwas; es gibt im ganzen Programm keine Stelle, die das könnte. --- ## Aktualisieren **Zwei Schritte, zwei Maschinen.** Erst baut der Arbeitsrechner die neue Fassung und legt sie in die Registry: ```bash Tools/image-veroeffentlichen.sh ``` Dann holt das NAS sie. In der Docker-App genügt das Aktualisieren des Projekts; über die Kommandozeile: ```bash docker compose pull && docker compose up -d ``` Migrationen der Datenbank laufen beim Start von selbst. Ein Rückschritt auf eine ältere Fassung ist **nicht** vorgesehen — vor einem Sprung lohnt eine Kopie von `config/`. --- ## Wenn etwas nicht geht ```bash docker compose logs -f flaro ``` | Zeichen | Ursache | |---|---| | `exec format error` | falsche Architektur — siehe Schritt 1 | | Mediathek bleibt leer | der Pfad in Flaro ist der des NAS statt der im Container | | „Zugriff verweigert" im Protokoll | Rechte, siehe `user:` oben | | Keine Plakate, Titel wie Dateinamen | kein TMDB-Zugang oder kein Netz | | Hardware-Beschleunigung greift nicht | `/dev/dri` nicht durchgereicht | Ein Gesundheitsendpunkt ohne Anmeldung: ```bash curl http://:8096/health ```