Damit das Image dort landet, wo das NAS es holen kann. **`.gitea/workflows/image.yml`** — Gitea baut selbst. Bei jedem Push auf `main` entsteht das Image für **beide** Architekturen und landet in der Registry desselben Gitea. Niemand muss daran denken, niemand muss angemeldet sein, und niemand kann die Architektur vergessen. Voraussetzung ist ein registrierter Act-Runner. Hat deiner keinen, läuft die Datei nie an — dafür gibt es den zweiten Weg. **`Tools/image-veroeffentlichen.sh`** — ein Befehl vom Arbeitsrechner, baut amd64 und arm64 und lädt hoch. Angemeldet wird einmalig von Hand; das Passwort tippt nur, wer es kennt. Beides legt `:latest` ab, dazu den Kurz-Hash und auf einem Git-Tag dessen Namen — damit sich eine Fassung festnageln lässt, statt immer „latest" zu ziehen. Die Anleitung bekommt vier neue Abschnitte: Gitea baut selbst, von Hand bauen, das Paket öffentlich stellen, und **die Registry im NAS eintragen** — also genau der Dialog „Quellname des Images", mit Alias `gitea` und Link `https://git.scarriffle.com/`. Für ein privates Paket ein Zugriffstoken mit `read:package`, nicht das Kontopasswort: ein Token lässt sich einzeln widerrufen. Die Beispiel-Compose zeigte auf `ghcr.io/scarriffle/flaro` — dort liegt nichts und lag nie etwas. Jetzt auf die Gitea-Registry. --- **Ein Fehler im eigenen Skript, gefunden beim ersten Lauf.** Die Prüfung „läuft Docker?" war `docker info | grep -q .` — und `grep -q` beendet die Pipe beim ersten Treffer, Docker bekommt SIGPIPE, und mit `set -o pipefail` gilt das als Fehlschlag. Das Skript meldete „Docker läuft nicht", während Docker lief und gerade ein Image gebaut hatte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8.1 KiB
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:<fassung> 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:
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
Drei Wege. Der erste ist der bequemste, 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 · Gitea baut selbst
.gitea/workflows/image.yml liegt im Projekt. Bei jedem Push auf main
baut Gitea das Image für beide Architekturen und legt es ab — ohne dass
jemand daran denken muss, und ohne Anmeldung am Arbeitsrechner.
Voraussetzung ist ein registrierter Act-Runner. Hat dein Gitea keinen, passiert nichts; dann gilt A2. Nachsehen unter Einstellungen → Actions → Runner. Ein Runner lässt sich als Container neben Gitea betreiben:
docker run -d --restart unless-stopped --name gitea-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
-e GITEA_INSTANCE_URL=https://git.scarriffle.com \
-e GITEA_RUNNER_REGISTRATION_TOKEN=<Token aus den Einstellungen> \
gitea/act_runner:latest
A2 · Von Hand vom Arbeitsrechner
Einmalig anmelden — das Passwort tippst du selbst ein:
docker login git.scarriffle.com
Danach genügt ein Befehl; er baut amd64 und arm64 und lädt hoch:
Tools/image-veroeffentlichen.sh
Mit einer Fassungsnummer, wenn du sie festnageln willst:
Tools/image-veroeffentlichen.sh 0.2.0
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 ein Gitea-Zugriffstoken ein
(nicht dein Kontopasswort: ein Token lässt sich einzeln widerrufen, unter
Einstellungen → Anwendungen → Zugriffstoken, Berechtigung read:package).
In der Compose-Datei steht dann:
image: git.scarriffle.com/scarriffle/flaro:latest
Weg B — als Datei hochladen
Ohne Registry, dafür bei jedem Update von Hand.
docker buildx build --platform linux/amd64 \
-f server/Dockerfile -t flaro:latest --load .
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:
docker load < /volume1/docker/flaro.tar.gz
In der Compose-Datei steht dann schlicht image: flaro:latest.
Weg C — auf dem NAS bauen
Geht, lohnt sich aber selten: der Bau braucht den Quelltext, Node, das
.NET-SDK als Zwischenschritt und ordentlich Arbeitsspeicher. Die Docker-App
von UGREEN kann build: in einer Compose-Datei ausserdem nicht immer.
Schritt 3: Die Compose-Datei
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:
user: "1001:100"
Welche Kennung gilt, sagt auf dem NAS:
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
docker compose up -d
Dann im Browser http://<nas>:8096 öffnen. Es erscheint der
Einrichtungsassistent:
- Administratorkonto anlegen — Benutzername und Passwort, mindestens acht Zeichen.
- Unter Verwaltung → Mediatheken eine Mediathek hinzufügen. Beim Ordner
gehört der Pfad im Container hinein, also
/media/Filme, nicht/volume1/Medien/Filme. - Scannen. Der Scan liest die Dateien, danach holt Flaro die Metadaten.
- 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
Mit Weg A:
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
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:
curl http://<nas>:8096/health