Der Runner auf dem NAS scheitert an der Docker-App des UGREEN: sie lehnt den Einhängepunkt /var/run/docker.sock ab. Nachgewiesen durch Halbieren der Compose-Datei — ohne diese eine Zeile wird das Projekt angelegt, mit ihr nicht, und die Meldung nennt keinen Grund. Übrig blieben Docker-in-Docker mit privileged oder der Weg über SSH an der Oberfläche vorbei. Beide geben dem Runner faktisch Root auf dem NAS, und das für eine Aufgabe, die der Arbeitsrechner ohnehin erledigen kann: er ist für die Apps nötig, weil Xcode nirgendwo sonst läuft. Der Workflow löst deshalb nicht mehr bei jedem Push aus. Sonst sammelt Gitea Läufe an, die niemand abarbeitet, und die Actions-Seite füllt sich mit Leichen. Er bleibt als workflow_dispatch stehen, der Auslöser ist mit drei Zeilen wieder da. Die Anleitung stellt das Bauen vom Arbeitsrechner nach vorn und hält zwei Dinge fest, die beim Einrichten Zeit gekostet haben: die Docker-App zieht Images nicht selbst, und die Anmeldung an der Registry will ein Zugriffstoken statt des Kontopassworts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
315 lines
9.3 KiB
Markdown
315 lines
9.3 KiB
Markdown
# 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:
|
|
|
|
```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://<nas>: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://<nas>:8096/health
|
|
```
|