Files
Flaro/docs/NAS-EINRICHTEN.md
T
ScarriffleandClaude Opus 5 c12748e262 Ein Weg vom Quelltext in die Registry — und von dort aufs NAS
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>
2026-10-04 08:08:22 +02:00

287 lines
8.1 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
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:
```bash
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:
```bash
docker login git.scarriffle.com
```
Danach genügt ein Befehl; er baut amd64 **und** arm64 und lädt hoch:
```bash
Tools/image-veroeffentlichen.sh
```
Mit einer Fassungsnummer, wenn du sie festnageln willst:
```bash
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:
```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 — 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
```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
Mit Weg A:
```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
```