Benutzer-Werkzeuge

Webseiten-Werkzeuge


it:thinkcentreserver

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
it:thinkcentreserver [2026/06/17 14:53] – [7.1 Brother ADS-1800W Konfiguration] matthiasit:thinkcentreserver [2026/06/30 15:43] (aktuell) – [6.1 Nginx Proxy Manager (NPM)] matthias
Zeile 85: Zeile 85:
 | **Docker-Configs & Indizes (High-End)** | | | | | **Docker-Configs & Indizes (High-End)** | | | |
 | ''/opt/docker/[dienstname]/config'' | NVMe SSD | Konfigurationsdaten (Nextcloud, HA, Pi-hole, NPM) | ''${PATH_SSD}'' | | ''/opt/docker/[dienstname]/config'' | NVMe SSD | Konfigurationsdaten (Nextcloud, HA, Pi-hole, NPM) | ''${PATH_SSD}'' |
 +| ''/opt/docker/homeassistant/'' | NVMe SSD | HA-Konfiguration (''configuration.yaml'', ''automations.yaml'', ''zigbee.db'') | ''${PATH_SSD}'' |
 | ''/opt/docker/nextcloud/apps'' | NVMe SSD | Nextcloud Custom-Apps (Ergänzt wegen Compose-Konsistenz) | ''${PATH_SSD}'' | | ''/opt/docker/nextcloud/apps'' | NVMe SSD | Nextcloud Custom-Apps (Ergänzt wegen Compose-Konsistenz) | ''${PATH_SSD}'' |
 | ''/opt/docker/nextcloud/db'' | NVMe SSD | MariaDB-Datenbank (Nextcloud & Ghost) | ''${PATH_SSD}'' | | ''/opt/docker/nextcloud/db'' | NVMe SSD | MariaDB-Datenbank (Nextcloud & Ghost) | ''${PATH_SSD}'' |
Zeile 92: Zeile 93:
 | ''/mnt/sata-ssd/homeassistant/db'' | SATA-SSD | Home Assistant Recorder-Datenbank (''home-assistant_v2.db'') | ''${PATH_SATA}'' | | ''/mnt/sata-ssd/homeassistant/db'' | SATA-SSD | Home Assistant Recorder-Datenbank (''home-assistant_v2.db'') | ''${PATH_SATA}'' |
 | ''/mnt/sata-ssd/paperless/consume'' | SATA-SSD | Paperless-ngx Einzugsordner (Permanenter OCR-Scan) | ''${PATH_SATA}'' | | ''/mnt/sata-ssd/paperless/consume'' | SATA-SSD | Paperless-ngx Einzugsordner (Permanenter OCR-Scan) | ''${PATH_SATA}'' |
-| ''/mnt/sata-ssd/paperless/data'' | SATA-SSD | Interner Suchindex von Paperless-ngx | ''${PATH_SATA}'' |+| ''/mnt/sata-ssd/paperless/data'' | SATA-SSD | Interner Suchindex und Dokumentenstruktur von Paperless-ngx | ''${PATH_SATA}''
 +| ''/mnt/sata-ssd/paperless/data/documents/originals/'' | SATA-SSD | Strukturierte Originaldokumente (Unterordner: ''gemeinsam/'', ''matthias/'', ''jana/''| ''${PATH_SATA}'' |
 | ''/mnt/sata-ssd/immich/encoded-video'' | SATA-SSD | Temporäre Arbeitsdateien für das Video-Transcoding | ''${PATH_SATA}'' | | ''/mnt/sata-ssd/immich/encoded-video'' | SATA-SSD | Temporäre Arbeitsdateien für das Video-Transcoding | ''${PATH_SATA}'' |
 | ''/mnt/sata-ssd/ghost/content'' | SATA-SSD | Ghost-CMS Inhalt (Themes, Bilder, Uploads) | ''${PATH_SATA}'' | | ''/mnt/sata-ssd/ghost/content'' | SATA-SSD | Ghost-CMS Inhalt (Themes, Bilder, Uploads) | ''${PATH_SATA}'' |
Zeile 110: Zeile 112:
 PATH_SATA=/mnt/sata-ssd PATH_SATA=/mnt/sata-ssd
 PATH_HDD=/media/usbhdd1/ocdata PATH_HDD=/media/usbhdd1/ocdata
 +PATH_HA_DB=/mnt/sata-ssd/homeassistant/db
 +
 +USER_ID=1000
 +GROUP_ID=1000
 +
 +# --- KEEPASS-REFERENZEN ---
 DB_ROOT_PASSWORD=EinSehrSicheresRootPasswort123! DB_ROOT_PASSWORD=EinSehrSicheresRootPasswort123!
 DB_PASSWORD=NextcloudDbPasswort456! DB_PASSWORD=NextcloudDbPasswort456!
Zeile 119: Zeile 127:
  
 <code yaml> <code yaml>
-version: '3.8' 
- 
 networks: networks:
   server-network:   server-network:
Zeile 215: Zeile 221:
       - server-network       - server-network
  
-  # --- Nextcloud ---+ 
 +# --- Nextcloud ---
  
   nextcloud:   nextcloud:
Zeile 236: Zeile 243:
       - server-network       - server-network
  
-  # --- Paperless-ngx ---+# --- Paperless-ngx ---
  
   paperless-redis:   paperless-redis:
Zeile 254: Zeile 261:
       - paperless-redis       - paperless-redis
     ports:     ports:
-      - "8090:8000"+      - "8090:8000"  # Intern läuft Paperless auf 8000, wir legen es auf Port 8090 am TC
     volumes:     volumes:
       - ${PATH_SSD}/paperless/config:/usr/src/paperless/data       - ${PATH_SSD}/paperless/config:/usr/src/paperless/data
Zeile 262: Zeile 269:
       - PAPERLESS_REDIS=redis://paperless-redis:6379       - PAPERLESS_REDIS=redis://paperless-redis:6379
       - PAPERLESS_TIME_ZONE=${TZ}       - PAPERLESS_TIME_ZONE=${TZ}
-      - PAPERLESS_OCR_LANGUAGE=deu+eng +      - PAPERLESS_OCR_LANGUAGE=deu+eng  # Deutsche und englische Texterkennung laden 
-      - USER_ID=1000 +      - USER_ID=1000  # Entspricht deinem User matthias (PUID) 
-      - GROUP_ID=1000 +      - GROUP_ID=1000  # Entspricht deiner Gruppe matthias (PGID) 
-      - PAPERLESS_CONSUMER_POLLING=10+      - PAPERLESS_CONSUMER_POLLING=15 
 +      - PAPERLESS_CONSUMER_POLLING_RETRY_COUNT=10 
 +      - PAPERLESS_CONSUMER_POLLING_DELAY=5
       - PAPERLESS_CONSUMER_USE_INOTIFY=false       - PAPERLESS_CONSUMER_USE_INOTIFY=false
       - PAPERLESS_CONSUMER_RECURSIVE=true       - PAPERLESS_CONSUMER_RECURSIVE=true
 +      - PAPERLESS_CONSUMER_ENABLE_BARCODES=true
 +      - PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE=true
 +      - PAPERLESS_CONSUMER_ASN_BARCODE_PREFIX=ASN
 +      - PAPERLESS_CONSUMER_BARCODE_DPI=600
 +      - PAPERLESS_CONSUMER_BARCODE_UPSCALE=2
 +      - CELERY_WORKER_CONCURRENCY=4
 +      - 'PAPERLESS_OCR_USER_ARGS={"continue_on_soft_render_error": true}'
 +
 +    networks:
 +      - server-network
 +
 +
 +# --- Home Assistant Stack ---
 +
 +  homeassistant:
 +    image: ghcr.io/home-assistant/home-assistant:latest
 +    container_name: homeassistant
 +    restart: unless-stopped
 +    volumes:
 +      # Performance-Kritisch auf NVMe (alles außer die dicke DB)
 +      - ${PATH_SSD}/homeassistant:/config
 +      # Schreibintensiver DB-Ordner komplett auf die SATA-SSD umgebogen
 +      - /mnt/sata-ssd/homeassistant/db:/config/db
 +    environment:
 +      - TZ=${TZ}
 +    network_mode: "host" # Für Entdeckungsdienste (mDNS/UPnP) im Smart Home zwingend empfohlen
 +
 +  mosquitto:
 +    image: eclipse-mosquitto:2
 +    container_name: mosquitto
 +    restart: unless-stopped
 +    ports:
 +      - "1883:1883"
 +      - "9001:9001"
 +    volumes:
 +      - ${PATH_SSD}/mosquitto/config:/mosquitto/config
 +      - ${PATH_SSD}/mosquitto/data:/mosquitto/data
 +      - ${PATH_SSD}/mosquitto/log:/mosquitto/log
     networks:     networks:
       - server-network       - server-network
Zeile 306: Zeile 353:
  
 ==== 5.2 Docker-Updates ==== ==== 5.2 Docker-Updates ====
 +Da die Docker-Infrastruktur aus Performance- und Strukturgründen in zwei separate Stacks aufgeteilt ist (Haupt-Infrastruktur und Immich), müssen Updates in den jeweiligen Projektverzeichnissen getriggert werden.
 +
 +=== Manueller Update-Prozess ===
 +Der optimierte Dreischritt holt die neuesten Images, startet geänderte Container neu und räumt verwaiste Image-Leichen direkt auf:
 <code bash> <code bash>
-Standard-Vierzeiler für Updates über docker-compose:+1. Haupt-Infrastruktur updaten
 cd /opt/docker/ cd /opt/docker/
-docker compose pull +docker compose pull && docker compose up -d --remove-orphans && docker image prune -a 
-docker compose up -d + 
-docker image prune -f+# 2. Immich Foto-Infrastruktur separat updaten 
 +cd /opt/docker/immich/ 
 +docker compose pull && docker compose up -d --remove-orphans && docker image prune -a 
 +</code> 
 + 
 +=== Automatisierung via Bash-Alias (Empfohlen) === 
 +Um im Alltag nicht manuell in die Verzeichnisse springen zu müssen, ist in der ''~/.bashrc'' des Users ''matthias'' ein globaler Verkettungs-Alias hinterlegt: 
 + 
 +<code> 
 +alias update-server='cd /opt/docker && sudo docker compose pull && sudo docker compose up -d --remove-orphans && cd /opt/docker/immich && sudo docker compose pull && sudo docker compose up -d --remove-orphans && docker image prune -af && cd ~' 
 +</code> 
 + 
 +**Wartungsbefehl im Alltag:** 
 +<code bash> 
 +update-server
 </code> </code>
  
Zeile 319: Zeile 384:
 du -h --max-depth=1 du -h --max-depth=1
 </code> </code>
 +
 +==== 5.4 Shell-Befehle ====
 +^ Kategorie ^ Befehl ^ Beschreibung / Parameter ^
 +| **Speicher** | ''du -hd 1 /pfad/ | sort -h'' | Zeigt Ordnergröße der ersten Unterebene, menschlich lesbar (''-h''), numerisch sortiert (''sort -h''): |
 +| | ''df -h'' | Zeigt freien/belegten Speicherplatz aller gemounteten Partitionen. |
 +| **Transfer** | ''scp -r user@ip:/quelle/ "C:\ziel"'' | **Lokal in Win-PowerShell:** Rekursiver Download (''-r'') vom Server zu Windows. |
 +| | ''scp /quelle user@ip:/ziel/'' | Kopiert Datei via SSH von Linux zu Linux. |
 +| **Immich-CLI** | **In Win-PowerShell (Sitzungsvariablen):** ''$env:IMMICH_INSTANCE="http://192.168.178.128:2283/api"'' ''$env:IMMICH_KEY="wVujBLe3..."'' | Setzt die Verbindungsparameter für das Immich-CLI in der aktuellen Windows-Sitzung, um Parameter-Fehler zu vermeiden. |
 +| | ''immich upload --recursive "C:\pfad\"'' | Schiebt lokale Windows-Ordnerstrukturen stabil und parallel über das Netzwerk auf das TC (Sitzungsvariablen vorausgesetzt). |
 +| **Rsync** | ''rsync -avzP --delete /quell/ /ziel/'' | **Backup-Standard:** Synchronisiert Ordner. ''-a'' (Rechte), ''-v'' (Details), ''-z'' (Kompression), ''-P'' (Fortschritt+Resume), ''--delete'' (löscht verwaiste Ziel-Dateien). |
 +| **Docker** | ''docker compose up -d'' | Startet alle Container des Verzeichnisses im Hintergrund (Detached). |
 +| | ''docker compose up -d [name]'' | Startet/Aktualisiert nur einen spezifischen Dienst (z. B. ''homeassistant''). |
 +| | ''docker compose down'' | Stoppt Container und baut Docker-Netzwerk ab (Daten auf SSDs bleiben unberührt). |
 +| | ''docker compose ps -a'' | Zeigt alle Container des Stacks mit aktuellem Status (Up, Exited) und Ports an. |
 +| | ''docker compose stop'' | Pausiert Container temporär (ohne Netzwerkabbau). |
 +| | ''docker compose pull'' | Lädt neuere Container-Images laut Definition in ''docker-compose.yml'' herunter. |
 +| | ''docker image prune -a'' | Löscht ungenutzte, alte Image-Leichen und gibt massig Speicherplatz auf NVMe frei. |
 +| **Logs** | ''docker compose logs -f --tail 50'' | Zeigt die letzten 50 Log-Zeilen aller Dienste an und bleibt live geöffnet (''-f''). |
 +| | ''docker logs -f [name]'' | Zeigt Live-Logs eines spezifischen Containers (z. B. ''homeassistant''). |
 +| **Rechte** | ''sudo chown -R user:group /pfad/'' | Ändert den Besitzer eines Verzeichnisses rekursiv (''-R''). |
 +| | ''sudo chmod -R 755 /pfad/'' | Setzt Rechte rekursiv: Besitzer darf alles (7), Gruppe/Andere nur Lesen/Ausführen (5). |
  
 ===== 6. Dienst-spezifische Notizen ===== ===== 6. Dienst-spezifische Notizen =====
  
 ==== 6.1 Nginx Proxy Manager (NPM) ==== ==== 6.1 Nginx Proxy Manager (NPM) ====
 +
 === Installation & Protokoll === === Installation & Protokoll ===
   * **Interner Port / Protokoll:** 80 (HTTP), 443 (HTTPS), 81 (Web-UI Admin)   * **Interner Port / Protokoll:** 80 (HTTP), 443 (HTTPS), 81 (Web-UI Admin)
   * **Externer Zugriff:** Ports 80 & 443 direkt im Router auf das TC weitergeleitet.   * **Externer Zugriff:** Ports 80 & 443 direkt im Router auf das TC weitergeleitet.
   * **Abhängigkeiten:** Keinerlei Abhängigkeiten. Das Einfallstor für alle HTTP-Dienste.   * **Abhängigkeiten:** Keinerlei Abhängigkeiten. Das Einfallstor für alle HTTP-Dienste.
 +
 === Bedienung & Wichtige Befehle === === Bedienung & Wichtige Befehle ===
-  * **Web-UI:** [[http://192.168.178.200:81]] (temporär [[http://192.168.178.128:81]]) +  * **Web-UI:** [[http://192.168.178.128:81]] (Zentral auf dem ThinkCentre
-  * **Tuning:** In den Proxy-Hosts standardmäßig "Block Common Exploits" und "HTTP/2 Support" für Performance und Sicherheit aktivieren. Für Datei-Uploads (Nextcloud/Immich) ''client_max_body_size 512M;'' unter Advanced eintragen.+  * **Tuning:** In den Proxy-Hosts standardmäßig "Block Common Exploits" und "HTTP/2 Support" für Performance und Sicherheit aktivieren. Für massive Datei-Uploads (Nextcloud/Immich) zwingend ''client_max_body_size 0;'' (hebt das Limit komplett auf) oder ''client_max_body_size 10G;'' unter Advanced eintragen. 
 + 
 +=== Aktive Domain-Struktur (Manitu CNAME) === 
 +Alle Subdomains der Hauptdomain ''tietge.org'' sind im Manitu-Kundencenter als **CNAME-Eintrag** auf das DynDNS ''pfogel.selfhost.bz.'' gemappt, um dynamische IP-Wechsel der FritzBox abzufangen: 
 + 
 +^ Subdomain ^ Internes Docker-Ziel (TC) ^ Beschreibung / Zweck ^ 
 +| ''wg-wiki.tietge.org'' | ''wg-wiki:80'' | WG-DokuWiki Instanz | 
 +| ''band-wiki.tietge.org'' | ''band-wiki:80'' | Band-DokuWiki Instanz | 
 +| ''ak-wiki.tietge.org'' | ''ak-wiki:80'' | Arbeitskreis-DokuWiki Instanz | 
 +| ''nextcloud.tietge.org'' | ''nextcloud:80'' | Neue Familien-Zentrale auf dem TC | 
 +| ''fotos.tietge.org'' | ''immich_server:2283'' | Immich Foto-Infrastruktur | 
 +| ''porgys.tietge.org'' | ''ghost:2368'' | Ghost CMS Band-Webseite | 
 + 
 +=== Migrations- & Routing-Architektur (Fernzugriff) === 
 +Um während der Migrationsphase Ausfallzeiten zu verhindern, fungiert der NPM auf dem ThinkCentre als **zentrale Weiche (Reverse Proxy)** im Heimnetzwerk. Da er sowohl im isolierten ''server-network'' als auch im normalen LAN agiert, routet er den Traffic anhand der aufrufenden Domain bzw. des Subpfads: 
 + 
 +== 1. Fallback für bestehende Alt-Systeme (Raspberry Pi) == 
 +Damit alte Lesezeichen und Smartphone-Syncs über die Selfhost-Domain nicht brechen, leitet ein "Catch-All"-Proxy-Host Anfragen an ''pfogel.selfhost.bz'' per internem HTTPS (Port 443) direkt weiter an den alten Raspberry Pi (''192.168.178.200''). Da dort aktuell unter anderem noch die aktive Nextcloud läuft, bleibt dieser Haupt-Forward unberührt, bis alle Altdienste vollständig migriert sind. SSL-Zertifikate kollidieren hierbei nicht, da der NPM die äußere Verschlüsselung übernimmt und intern verschlüsselt mit dem Pi spricht (SSL-Terminierung). 
 + 
 +== 2. Nahtlose Wiki-Migration via Custom Locations (Zwei-Wege-System) == 
 +Die drei DokuWikis wurden erfolgreich auf das ThinkCentre migriert und laufen nativ und ohne Unterordner auf ihren jeweiligen ''tietge.org''-Subdomains. Damit alte Lesezeichen über die Selfhost-Unterpfade nicht ins Leere laufen (oder auf dem RPi sterben), fängt der NPM diese Pfade gezielt ab und leitet sie per Nginx-Rewrite transparent und unter Beibehaltung aller Unterseiten auf die neuen Domains um. 
 + 
 +Dazu sind im NPM unter dem Proxy-Host ''pfogel.selfhost.bz'' drei **Custom Locations** definiert: 
 + 
 +**Band-Wiki:** 
 +  * **Define Location:** ''/band-wiki'' 
 +  * **Scheme & Ziel:** ''http://192.168.178.128:8081'' 
 +  * **Erweiterte Nginx-Konfiguration (Zahnrad):** 
 +<code nginx> 
 +rewrite ^/band-wiki(.*)$ https://band-wiki.tietge.org$1 permanent; 
 +</code> 
 + 
 +**WG-Wiki:** 
 +  * **Define Location:** ''/wg-wiki'' 
 +  * **Scheme & Ziel:** ''http://192.168.178.128:8083'' 
 +  * **Erweiterte Nginx-Konfiguration (Zahnrad):** 
 +<code nginx> 
 +rewrite ^/wg-wiki(.*)$ https://wg-wiki.tietge.org$1 permanent; 
 +</code> 
 + 
 +**AK-Wiki:** 
 +  * **Define Location:** ''/ak-wiki'' 
 +  * **Scheme & Ziel:** ''http://192.168.178.128:8082'' 
 +  * **Erweiterte Nginx-Konfiguration (Zahnrad):** 
 +<code nginx> 
 +rewrite ^/ak-wiki(.*)$ https://ak-wiki.tietge.org$1 permanent; 
 +</code>
  
 +== 3. Zukünftiger Nextcloud-Umzug ==
 +Sobald die Nextcloud auf das TC migriert wird, wird analog zu den Wikis eine Custom Location für ''/nextcloud'' eingerichtet, um den Traffic aus dem Selfhost-Proxy herauszuschneiden. Bis dahin verbleibt der Nextcloud-Traffic im globalen Fallback auf den Raspberry Pi (''192.168.178.200'').
 ==== 6.2 Pi-hole ==== ==== 6.2 Pi-hole ====
 === Installation & Protokoll === === Installation & Protokoll ===
Zeile 386: Zeile 522:
  
 ==== 6.9 Paperless-ngx ==== ==== 6.9 Paperless-ngx ====
 +=== Shell Befehle ===
 +  * Verzeichnis: ''cd /opt/docker/''
 +  * Scan Attribute Dokumente ''docker compose exec -it paperless-webserver python3 /usr/src/paperless/src/manage.py document_create_classifier''
 +
 === Installation & Protokoll === === Installation & Protokoll ===
   * **Interner Port / Protokoll:** 8000 (Auf Host-Port 8090 gemappt)   * **Interner Port / Protokoll:** 8000 (Auf Host-Port 8090 gemappt)
Zeile 393: Zeile 533:
 === Besonderheiten & Pfadtrennung === === Besonderheiten & Pfadtrennung ===
 Das System nutzt ein dreistufiges Mapping zur optimalen Performanceverteilung: Das System nutzt ein dreistufiges Mapping zur optimalen Performanceverteilung:
-  1. **NVMe SSD:** Server-Konfigurationen und App-Daten (''/usr/src/paperless/data''). +  **NVMe SSD:** Server-Konfigurationen und App-Daten (''/usr/src/paperless/data''). 
-  2. **SATA-SSD (Stoßdämpfer):** Schreibintensiver, permanenter Suchindex sowie der ''consume''-Ordner für das Datei-Scanning (''/usr/src/paperless/consume''). +  **SATA-SSD (Stoßdämpfer):** Schreibintensiver, permanenter Suchindex sowie der ''consume''-Ordner für das Datei-Scanning (''/usr/src/paperless/consume''). 
-  3. **Massenspeicher:** Finale, fertig verarbeitete PDF-Archivdateien werden unter ''/usr/src/paperless/media'' abgelegt. *(Aktuell auf SATA-SSD gemappt, vorbereitet für den direkten HDD-Wechsel über ${PATH_SATA}).*+  **Massenspeicher:** Finale, fertig verarbeitete PDF-Archivdateien werden unter ''/usr/src/paperless/media'' abgelegt. *(Aktuell auf SATA-SSD gemappt, vorbereitet für den direkten HDD-Wechsel über ${PATH_SATA}).*
  
 === Linux-Dateisystem & FTP-Brücke (fstab Bind-Mounts) === === Linux-Dateisystem & FTP-Brücke (fstab Bind-Mounts) ===
Zeile 439: Zeile 579:
 //Hinweis für die Weboberfläche: Beim Erstellen eines neuen Arbeitsablaufs muss das Feld "Sortierreihenfolge" zwingend mit einer Zahl (z.B. 1) befüllt werden, da Paperless den Workflow sonst nicht speichert. Der Inhaltsabgleichsalgorithmus wird auf "Keiner" gesetzt, da das Verzeichnis-Polling über die Variable PAPERLESS_CONSUMER_RECURSIVE=true die Zuteilung vollständig steuert.// //Hinweis für die Weboberfläche: Beim Erstellen eines neuen Arbeitsablaufs muss das Feld "Sortierreihenfolge" zwingend mit einer Zahl (z.B. 1) befüllt werden, da Paperless den Workflow sonst nicht speichert. Der Inhaltsabgleichsalgorithmus wird auf "Keiner" gesetzt, da das Verzeichnis-Polling über die Variable PAPERLESS_CONSUMER_RECURSIVE=true die Zuteilung vollständig steuert.//
 ==== 6.10 Immich (Foto-Infrastruktur) ==== ==== 6.10 Immich (Foto-Infrastruktur) ====
 +
 +Selbstgehostete Foto- und Videoplattform als performanter Ersatz für Google Photos.
 +
 === Installation & Protokoll === === Installation & Protokoll ===
-  * **Interner Port / Protokoll:** 2283 (HTTP) +  * **Interner Port/Protokoll:** 2283 (HTTP) 
-  * **Externer Zugriff:** NPM Proxy Host mit aktiven Websockets+  * **Lokale Web-UI:** http://192.168.178.128:2283/ 
-  * **Abhängigkeiten:** Benötigt ''immich-db'' (Postgres mit Vektorerweiterung) und ''nextcloud-redis''+  * **Externer Zugriff:** Über NPM Proxy Host mit aktiven Websockets und ''client_max_body_size 512M;'' 
-=== Besonderheiten (Das perfekte Scroll-Tuning) === +  * **Abhängigkeiten:** Nutzt eine isolierte PostgreSQL-Datenbank mit Vektorerweiterung (''pgvecto-rs'') und teilt sich den zentralen Redis-Cache.
-Um das flüssige Durchscrollen der Handy-Timeline ohne NVMe-Verschleiß zu realisieren, ist der Container in drei Zonen zerlegt: +
-  1. **NVMe SSD:** Speicherort für ''/thumbs'' (Kleine WebP/JPEG-Vorschaubilder für die App-Timeline). +
-  2. **SATA-SSD:** Speicherort für ''/encoded-video'' (Temporärer Arbeitsordner für rechenintensives Video-Transcoding)+
-  3. **4TB HDD1:** Speicherort für ''/library'' und ''/upload'' (Die originalen, schweren Bildund Videodateien).+
  
 +=== Das 3-Zonen-Speicher-Mapping ===
 +
 +Um maximales Scroll-Tuning in der App ohne NVMe-Verschleiß zu realisieren, ist der Dienst physisch strikt getrennt:
 +  * **1. High-End Layer (NVMe SSD):** Die kritische PostgreSQL-Datenbank liegt zwecks maximaler IOPS unter ''/opt/docker/immich/db''.
 +  * **2. Stoßdämpfer Layer (SATA-SSD):** Rechenintensive Caches, temporäres Video-Transcoding (''/mnt/sata-ssd/immich/encoded-video'') sowie die generierten Timeline-Vorschaubilder (''/mnt/sata-ssd/immich/thumbs'').
 +  * **3. Vorläufiger Massenspeicher (SATA-SSD):** Das Datengrab für die Originalmedien liegt testweise temporär unter ''/mnt/sata-ssd/immich/original-media''.
 +
 +=== Lokale Docker-Infrastruktur ===
 +
 +Im Gegensatz zur globalen ''docker-compose.yml'' (Kapitel 3.2) wird Immich aus Gründen der Übersicht und Wartbarkeit **in einem separaten Verzeichnis mit eigener Konfiguration** betrieben, klinkt sich jedoch nahtlos in das globale ''server-network'' ein.
 +
 +== 1. Umgebungsvariablen (/opt/docker/immich/.env) ==
 +<code env>
 +IMMICH_VERSION=release
 +TZ=Europe/Berlin
 +PUID=1000
 +PGID=1000
 +
 +# Vorläufiger Pfad auf SATA-SSD (Datengrab)
 +UPLOAD_LOCATION=/mnt/sata-ssd/immich/original-media
 +DB_PASSWORD=ImmichPostgresPasswort789!
 +</code>
 +
 +== 2. Docker-Compose (/opt/docker/immich/docker-compose.yml) ==
 +Die Konfiguration nutzt explizit das ''cpuset''-Flag, um den Kern-Containern vollen Zugriff auf alle 4 Kerne und 8 Threads der AMD Ryzen 5 PRO 3400GE CPU zu gewähren. Die originalen Volume-Vorgaben der Entwickler (''/data'') bleiben unangetastet, während das SSD-Mapping über spezifische Unterpfade angedockt wird.
 +
 +<code yaml>
 +name: immich
 +
 +services:
 +  immich-server:
 +    container_name: immich_server
 +    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
 +    cpuset: "0-7" # Zuweisung aller 8 CPU-Threads
 +    volumes:
 +      - ${UPLOAD_LOCATION}:/data # Originalzeile unangetastet
 +      - /mnt/sata-ssd/immich/thumbs:/data/thumbs # SSD-Tuning Thumbs
 +      - /mnt/sata-ssd/immich/encoded-video:/data/encoded-video # SSD-Tuning Transcoding
 +      - /etc/localtime:/etc/localtime:ro
 +    env_file:
 +      - .env
 +    ports:
 +      - 2283:2283
 +    depends_on:
 +      - redis
 +      - database
 +    restart: unless-stopped
 +    networks:
 +      - server-network
 +
 +  immich-machine-learning:
 +    container_name: immich_machine_learning
 +    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
 +    cpuset: "0-7"
 +    volumes:
 +      - /mnt/sata-ssd/immich/thumbs:/data/thumbs
 +    env_file:
 +      - .env
 +    restart: unless-stopped
 +    networks:
 +      - server-network
 +
 +  redis:
 +    container_name: immich_redis
 +    image: docker.io/redis:6.2-alpine
 +    restart: unless-stopped
 +    networks:
 +      - server-network
 +
 +  database:
 +    container_name: immich_postgres
 +    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0
 +    environment:
 +      POSTGRES_DB: immich
 +      POSTGRES_USER: postgres
 +      POSTGRES_PASSWORD: ${DB_PASSWORD}
 +    volumes:
 +      - /opt/docker/immich/db:/var/lib/postgresql/data # DB zwingend auf NVMe
 +    restart: unless-stopped
 +    networks:
 +      - server-network
 +
 +networks:
 +  server-network:
 +    external: true
 +</code>
 +
 +=== Wartung & Zukünftiger HDD-Umbau ===
 +
 +== Initialer Bulk-Upload über Windows-PowerShell ==
 +Um große Medienmengen (z.B. >20 GB) stabil ohne Browser-Timeouts zu importieren, wird das offizielle Immich-CLI verwendet:
 +<code>
 +# CLI installieren und einloggen
 +npm install -g @immich/cli
 +immich login http://192.168.178.128:2283/api DEIN_API_KEY
 +
 +# Ordner rekursiv hochladen
 +immich upload --recursive --yes "C:\Pfad\zu\deinen\Bildern"
 +</code>
 +
 +== Spätere Migration auf das 4TB HDD-Datengrab ==
 +Sobald der Testbetrieb beendet ist, wird der Massenspeicher verlustfrei auf die ''HDD1'' (''/media/usbhdd1/ocdata/immich/'') ausgelagert. Das Vorgehen erfordert nur drei Schritte:
 +
 +1. Immich-Stack stoppen:
 +<code>
 +cd /opt/docker/immich && docker compose down
 +</code>
 +
 +2. Daten per ''rsync'' auf die HDD migrieren:
 +<code>
 +sudo rsync -avzP /mnt/sata-ssd/immich/original-media/ /media/usbhdd1/ocdata/immich/
 +</code>
 +
 +3. Pfad in der ''/opt/docker/immich/.env'' anpassen und Stack starten:
 +<code>
 +# Neue Zuweisung in der .env:
 +UPLOAD_LOCATION=/media/usbhdd1/ocdata/immich
 +
 +# Start:
 +docker compose up -d
 +</code>
 ==== 6.11 Ghost (CMS für die Porgys) ==== ==== 6.11 Ghost (CMS für die Porgys) ====
 === Installation & Protokoll === === Installation & Protokoll ===
Zeile 464: Zeile 724:
 Der gesamte Content-Ordner (Themes, Bilder) wird materialschonend auf der SATA-SSD abgelegt. Der gesamte Content-Ordner (Themes, Bilder) wird materialschonend auf der SATA-SSD abgelegt.
  
 +==== 6.12 Audioserve (Audio-Streaming) ====
 +
 +Audioserve ist eine in Rust geschriebene, extrem performante Lösung zum Streamen von Audiodateien (Hörbücher, Musik, Band-Aufnahmen) mit nativer Wellenform-Generierung.
 +
 +=== Docker Compose Konfiguration ===
 +Anzulegen unter ''${PATH_SSD}/docker/audioserve/docker-compose.yml''.
 +
 +<code yaml>
 +version: "3"
 +
 +services:
 +  audioserve:
 +    image: miko65/audioserve:latest
 +    container_name: audioserve
 +    restart: unless-stopped
 +    ports:
 +      - "3000:3000"
 +    environment:
 +      - TZ=${TZ}
 +      - AUDIOSERVE_GENERATE_NAMES=true
 +    volumes:
 +      # Musik/Audio-Archiv auf der großen HDD
 +      - ${PATH_SATA}/audio:/audio
 +      # Metadaten und Wellenform-Cache auf der schnellen SSD
 +      - ${PATH_SSD}/audioserve/data:/home/audioserve/.audioserve
 +    command:
 +      - /audio
 +    networks:
 +      - server-network
 +
 +networks:
 +  server-network:
 +    external: true
 +</code>
 +
 +=== Praxis-Hinweise ===
 +* **Wellenformen:** Beim ersten Laden eines Tracks berechnet der Container die Waveform. Auf dem ThinkCentre (8 Kerne) geschieht dies im Bruchteil einer Sekunde.
 +* **Sicherheit:** Standardmäßig fordert Audioserve beim ersten Aufruf im Webinterface das Festlegen eines Shared-Secrets (Passwort) für den Client-Zugriff.
 +
 +
 +==== 6.13 Vikunja (To-Do & Taskmanagement) ====
 +
 +Vikunja ist eine selbstgehostete, hochperformante Aufgabenverwaltung (Alternative zu Todoist / Trello). Die Architektur trennt strikt zwischen Frontend (Web) und Backend (API), nutzt hier aber das offizielle, schlanke Kombi-Image.
 +
 +=== Docker Compose Konfiguration ===
 +Anzulegen unter ''${PATH_SSD}/docker/vikunja/docker-compose.yml''.
 +
 +<code yaml>
 +version: "3"
 +
 +services:
 +  vikunja-db:
 +    image: postgres:16-alpine
 +    container_name: vikunja-db
 +    restart: unless-stopped
 +    environment:
 +      POSTGRES_USER: vikunja
 +      POSTGRES_PASSWORD: ${VIKUNJA_DB_PASSWORD}
 +      POSTGRES_DB: vikunja
 +    volumes:
 +      - ${PATH_SSD}/vikunja/db:/var/lib/postgresql/data
 +    networks:
 +      - server-network
 +
 +  vikunja:
 +    image: vikunja/vikunja:latest
 +    container_name: vikunja
 +    restart: unless-stopped
 +    ports:
 +      - "3456:3456"
 +    environment:
 +      VIKUNJA_DATABASE_HOST: vikunja-db
 +      VIKUNJA_DATABASE_PASSWORD: ${VIKUNJA_DB_PASSWORD}
 +      VIKUNJA_DATABASE_TYPE: postgres
 +      VIKUNJA_DATABASE_USER: vikunja
 +      VIKUNJA_DATABASE_DATABASE: vikunja
 +      VIKUNJA_SERVICE_JWTSECRET: ${VIKUNJA_JWT_SECRET}
 +      VIKUNJA_SERVICE_PUBLICURL: http://192.168.178.128:3456/
 +    volumes:
 +      - ${PATH_SSD}/vikunja/files:/app/vikunja/files
 +    depends_on:
 +      - vikunja-db
 +    networks:
 +      - server-network
 +
 +networks:
 +  server-network:
 +    external: true
 +</code>
 +
 +=== Praxis-Hinweise ===
 +* **Umgebungsvariablen:** Die Passwörter (''${VIKUNJA_DB_PASSWORD}'' und ein langer Zufallsstring für ''${VIKUNJA_JWT_SECRET}'') sollten in der zentralen ''.env''-Datei des Verzeichnisses hinterlegt werden.
 +* **Datenbanksicherung:** Der PostgreSQL-Container liegt zwecks maximaler IOPS-Performance vollständig auf der SSD.
 ===== 7 Scanner-Administration & Dokumenten-Einzug ===== ===== 7 Scanner-Administration & Dokumenten-Einzug =====
  
Zeile 476: Zeile 829:
   * **Profil Jana:** Zielordner: ''scan-jana'' | SSL/TLS: ''Nichts''   * **Profil Jana:** Zielordner: ''scan-jana'' | SSL/TLS: ''Nichts''
   * **Profil Gemeinsam:** Zielordner: ''scan-gemeinsam'' | SSL/TLS: ''Nichts''   * **Profil Gemeinsam:** Zielordner: ''scan-gemeinsam'' | SSL/TLS: ''Nichts''
- 
---- 
- 
 ==== 7.2 Multi-User-Workflows & Speicherpfade ==== ==== 7.2 Multi-User-Workflows & Speicherpfade ====
  
Zeile 498: Zeile 848:
  
 > **Hinweis zu gemeinsamen Dokumenten:** Da Paperless-ngx zwingend einen eindeutigen Besitzer pro Dokument verlangt, wird bei "Gemeinsam" ein Elternteil als Eigentümer gesetzt. Die geteilte Sichtbarkeit wird im Workflow über die Registerkarte **Aktionen -> Berechtigungen** gesteuert, indem dort der Gruppe ''Familie'' Lese- und Schreibrechte (RW) zugewiesen werden. > **Hinweis zu gemeinsamen Dokumenten:** Da Paperless-ngx zwingend einen eindeutigen Besitzer pro Dokument verlangt, wird bei "Gemeinsam" ein Elternteil als Eigentümer gesetzt. Die geteilte Sichtbarkeit wird im Workflow über die Registerkarte **Aktionen -> Berechtigungen** gesteuert, indem dort der Gruppe ''Familie'' Lese- und Schreibrechte (RW) zugewiesen werden.
- 
---- 
  
 ==== 7.3 Administration & Fehlerbehebung (Troubleshooting) ==== ==== 7.3 Administration & Fehlerbehebung (Troubleshooting) ====
it/thinkcentreserver.1781700798.txt.gz · Zuletzt geändert: von matthias