====== ThinkCentre Server Dokumentation ====== //Zweck dieser Seite: Zentrale Dokumentation des minimalen Debian headless Servers. Befehle bitte konsequent in den passenden Code-Blöcken hinterlegen, um schnelles Copy-Paste im Wartungsfall zu ermöglichen.// ===== 1. Systemübersicht & Hardware ===== //In diesem Kapitel wird die physikalische und logische Hardwarebasis dokumentiert. Hilfreich für IP-Suchen im Netzwerk oder beim Austausch von Komponenten.// ==== 1.1 Spezifikationen ==== ^ Komponente ^ Details | | Modell | Lenovo ThinkCentre M75q | | CPU | AMD Ryzen 5 PRO 3400GE| | RAM | 16 GB DDR4 RAM | | Betriebssystem | Debian 12 (Bookworm)| ==== 1.2 Netzwerkkonfiguration ==== //Tipp: IP-Adresse fest in der Fritz!Box über die MAC-Adresse reservieren, sobald der finale Wechsel von .50 (Test-IP) auf .200 (Ziel-IP) durchgeführt wurde.// * **Hostname:** [Hostname] * **IPv4-Adresse:** 192.168.178.200 (Ziel-IP nach Abschaltung des alten RPI) * **IPv6-Adresse:** [IPv6-Adresse] * **MAC-Adresse:** [MAC-Adresse] === Genutzte Ports & Weiterleitungen === ^ Dienst ^ Port Intern ^ Port Extern ^ Typ / Proxy | | SSH | 22 | Keine | Direct (Nur lokal) | | HTTP (Reverse Proxy) | 80 | 80 | Nginx Proxy Manager (Let's Encrypt Challenge) | | HTTPS (Reverse Proxy) | 443 | 443 | Nginx Proxy Manager (Zentraler SSL-Endpunkt) | | Proxy-Manager Web-UI | 81 | Keine | Nur lokal erreichbar | | Mosquitto MQTT | 1883 | Keine | Internes Smart-Home-Netzwerk | ==== 1.3 Festplatten-Topologie & I/O-Schichten ==== Um maximale Anwendungsperformance bei gleichzeitiger Schonung der Systemmedien zu erreichen, wird ein dreistufiges Speicher-Mapping eingesetzt: ^ Device ^ Typ ^ Belegung (I/O-Schicht) ^ Dateisystem ^ UUID | | ''/dev/nvme0n1'' | M.2 NVMe (Samsung PM981a 256GB) | **High-End Layer:** OS, Docker-Configs, DBs, Cache-Indizes, Immich-Thumbnails | ext4 | [UUID-NVME] | | ''/dev/sdc1'' | SATA-SSD (256GB) | **Stoßdämpfer-Layer:** Write-intensive Files (HA-Recorder, Paperless-Consume, Immich-Transcoding) | ext4 | [UUID-SATA] | | ''/dev/sda1'' / ''sdb1'' | 2x 4TB HDD (USB-Bundle) | **Datengrab-Layer:** Statische Massendaten (Nextcloud-Dateien, Immich-Originalmedien) | ext4 | [UUID-HDD] | ===== 2. Betriebssystem & Basis-Einrichtung ===== //Dokumentation der grundlegenden OS-Einrichtung. Dient als roter Faden, falls der Server jemals komplett neu aufgesetzt werden muss.// ==== 2.1 Installation ==== * Genutztes Basis-Image: ''debian-12.X.X-amd64-netinst.iso'' * Besonderheiten bei der Installation: Standard-Netinst ohne Desktop-Umgebung, nur SSH-Server und Standard-Systemwerkzeuge ausgewählt. ==== 2.2 Sicherheit & SSH ==== * **Haupt-User:** [User-Name] * **SSH-Sicherheit:** Passwort-Login in ''/etc/ssh/sshd_config'' deaktiviert (''PasswordAuthentication no''), nur Key-Authentifizierung aktiv. # Befehl zur Absicherung der SSH-Schlüsselrechte auf dem Client: chmod 600 ~/.ssh/id_rsa ==== 2.3 Speicher-Mounts (/etc/fstab) ==== //Wichtig: Alle Festplatten werden über ihre eindeutige UUID gemountet, um Bezeichnungsänderungen (sda/sdb) nach Reboots abzufangen.// # Auszug aus /etc/fstab für NVMe, SATA-Stoßdämpfer und das HDD-Datengrab: UUID=[UUID-NVME-HIER] / ext4 errors=remount-ro 0 1 UUID=[UUID-SATA-HIER] /mnt/sata-ssd ext4 defaults,nofail 0 2 UUID=[UUID-HDD-HIER] /media/usbhdd1/ocdata ext4 defaults,nofail 0 2 ===== 3. Docker-Infrastruktur ===== //Zentrale Verwaltung aller containerisierten Dienste. Die Infrastruktur nutzt ein gemeinsames Bridge-Netzwerk, um RAM durch geteilte Caches (Redis) und Datenbanken (MariaDB) zu sparen.// ==== 3.1 Verzeichnis-Struktur & Pfad-Mapping (.env) ==== //Diese Sektion dient als zentrale "Ground Truth" für das System. Sie zeigt im Wartungsfall sofort, wo Konfigurationen, schreibintensive Caches oder wichtige Systemdateien physisch liegen und wie sie über Umgebungsvariablen an Docker übergeben werden.// * **Zentraler Pfad für Compose-Dateien und Configs (Schnelle NVMe):** ''/opt/docker/'' === Das dreistufige Speicher-Mapping === ^ Pfad / Datei ^ Speicher-Medium ^ Zweck / Inhalt ^ Docker-Variable | | **System & Docker-Basis** | | | | | ''/etc/fstab'' | NVMe SSD | System-Mounts (UUIDs für NVMe, SATA-SSD und HDDs) | - | | ''/etc/ssh/sshd_config'' | NVMe SSD | SSH-Absicherung (Passwort-Login deaktiviert) | - | | ''/opt/docker/'' | NVMe SSD | Zentrales Verzeichnis für alle Compose-Dateien | - | | ''/opt/docker/.env'' | NVMe SSD | Globale Umgebungsvariablen & Passwörter | - | | **Docker-Configs & Indizes (High-End)** | | | | | ''/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/db'' | NVMe SSD | MariaDB-Datenbank (Nextcloud & Ghost) | ''${PATH_SSD}'' | | ''/opt/docker/immich/db'' | NVMe SSD | Postgres-Datenbank (Immich) | ''${PATH_SSD}'' | | ''/opt/docker/immich/thumbs'' | NVMe SSD | Immich-Vorschaubilder (Wichtig für flüssiges Scrollen!) | ''${PATH_SSD}'' | | **Schreibintensive Daten (Stoßdämpfer)** | | | | | ''/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/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/ghost/content'' | SATA-SSD | Ghost-CMS Inhalt (Themes, Bilder, Uploads) | ''${PATH_SATA}'' | | **Massendaten & Backups (Datengrab)** | | | | | ''/media/usbhdd1/ocdata/'' | 4TB HDD 1 | Nextcloud Benutzerdaten (Dokumente, Bilder, Uploads) | ''${PATH_HDD}'' | | ''/media/usbhdd1/ocdata/immich/'' | 4TB HDD 1 | Immich Originalmedien (Bilder & Videos im Originalzustand) | ''${PATH_HDD}'' | | ''/media/usbhdd1/ocdata/paperless/media''| 4TB HDD 1 | Finale, fertig verarbeitete Paperless-PDF-Archivdateien | ''${PATH_HDD}'' | | ''/media/usbhdd2/'' | 4TB HDD 2 | **Backup-Ziel:** Nächtliche rsync/rsnapshot-Sicherungen | - | === Inhalt der globalen .env-Datei === Zur sauberen Pfad- und Geheimnis-Trennung wird im Verzeichnis ''/opt/docker/'' eine Datei ''.env'' mit folgendem Inhalt gepflegt: TZ=Europe/Berlin PATH_SSD=/opt/docker PATH_SATA=/mnt/sata-ssd 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_PASSWORD=NextcloudDbPasswort456! IMMICH_DB_PASSWORD=ImmichPostgresPasswort789! GHOST_DB_PASSWORD=GhostMariaDbPasswort999! ==== 3.2 Die globale docker-compose.yml ==== //Zentrales Multi-Service-Skelett für alle Dienste. Passwörter und Pfade werden über die lokale ''.env'' gesteuert.// networks: server-network: name: server-network driver: bridge services: # --- INFRASTRUKTUR & SSL-BACKBONE --- nginx-proxy-manager: image: 'jc21/nginx-proxy-manager:latest' container_name: nginx-proxy-manager restart: unless-stopped ports: - '80:80' - '443:443' - '81:81' volumes: - ${PATH_SSD}/nginx-proxy-manager/data:/data - ${PATH_SSD}/nginx-proxy-manager/letsencrypt:/etc/letsencrypt networks: - server-network # --- DATENBANKEN & CACHES --- nextcloud-db: image: mariadb:10.11 container_name: nextcloud-db restart: unless-stopped command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci environment: - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - MYSQL_PASSWORD=${DB_PASSWORD} - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud volumes: - ${PATH_SSD}/nextcloud/db:/var/lib/mysql networks: - server-network nextcloud-redis: image: redis:alpine container_name: nextcloud-redis restart: unless-stopped networks: - server-network # --- DOKUWIKIS (Zukunftssicheres Linuxserver.io-Repository) --- band-wiki: image: lscr.io/linuxserver/dokuwiki:latest container_name: band-wiki environment: - PUID=1000 - PGID=1000 - TZ=${TZ} volumes: - ${PATH_SSD}/band-wiki/config:/config ports: - '8081:80' restart: unless-stopped networks: - server-network ak-wiki: image: lscr.io/linuxserver/dokuwiki:latest container_name: ak-wiki environment: - PUID=1000 - PGID=1000 - TZ=${TZ} volumes: - ${PATH_SSD}/ak-wiki/config:/config ports: - '8082:80' restart: unless-stopped networks: - server-network wg-wiki: image: lscr.io/linuxserver/dokuwiki:latest container_name: wg-wiki environment: - PUID=1000 - PGID=1000 - TZ=${TZ} volumes: - ${PATH_SSD}/wg-wiki/config:/config ports: - '8083:80' restart: unless-stopped networks: - server-network # --- Nextcloud --- nextcloud: image: nextcloud:30-apache container_name: nextcloud restart: unless-stopped depends_on: - nextcloud-db - nextcloud-redis volumes: - ${PATH_SSD}/nextcloud/html:/var/www/html - ${PATH_HDD}:/var/www/html/data environment: - MYSQL_PASSWORD=${DB_PASSWORD} - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - MYSQL_HOST=nextcloud-db - REDIS_HOST=nextcloud-redis networks: - server-network # --- Paperless-ngx --- paperless-redis: image: docker.io/library/redis:7 container_name: paperless-redis restart: unless-stopped volumes: - ${PATH_SSD}/paperless/redis:/data networks: - server-network paperless-webserver: image: ghcr.io/paperless-ngx/paperless-ngx:latest container_name: paperless-webserver restart: unless-stopped depends_on: - paperless-redis ports: - "8090:8000" # Intern läuft Paperless auf 8000, wir legen es auf Port 8090 am TC volumes: - ${PATH_SSD}/paperless/config:/usr/src/paperless/data - ${PATH_SATA}/paperless/data:/usr/src/paperless/media - ${PATH_SATA}/paperless/consume:/usr/src/paperless/consume environment: - PAPERLESS_REDIS=redis://paperless-redis:6379 - PAPERLESS_TIME_ZONE=${TZ} - PAPERLESS_OCR_LANGUAGE=deu+eng # Deutsche und englische Texterkennung laden - USER_ID=1000 # Entspricht deinem User matthias (PUID) - GROUP_ID=1000 # Entspricht deiner Gruppe matthias (PGID) - PAPERLESS_CONSUMER_POLLING=15 - PAPERLESS_CONSUMER_POLLING_RETRY_COUNT=10 - PAPERLESS_CONSUMER_POLLING_DELAY=5 - PAPERLESS_CONSUMER_USE_INOTIFY=false - 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: - server-network ==== 3.3 Reverse-Proxy & SSL ==== * **Genutzter Proxy:** Nginx Proxy Manager (NPM). Übernimmt die Portfreigaben nach außen und terminiert den SSL-Handshake. * **Zertifikatsverwaltung:** Vollautomatisch via Let's Encrypt (HTTP-01-Challenge). NPM verlängert alle Zertifikate selbstständig 30 Tage vor Ablauf. * **Domain-Mapping (CNAME-Delegierung):** Eigene Hauptdomains (wie ''tietge.org'' bei Manitu oder ''porgys.de'' bei Netcup) werden via DNS-Menü des Hosters per CNAME-Eintrag auf die heimische DynDNS-Adresse ''pfogel.selfhost.bz'' umgeleitet. Der NPM fängt den Traffic ab und verteilt ihn anhand des Domainnamens. ===== 4. Daten- & Backup-Konzept ===== //Überblick über die Sicherungsmechanismen. Wichtig für die regelmäßige Kontrolle.// ==== 4.1 Backup-Strategie ==== //Kurze Beschreibung: Was wird wann und wohin gesichert? (z.B. Täglich von NVMe auf SATA-HDD via rsnapshot).// ==== 4.2 Backup-Konfiguration & Automatisierung ==== # Hier wichtige Zeilen der Backup-Konfig (z.B. rsnapshot.conf) oder Cronjobs eintragen ==== 4.3 Datenbank-Sicherung ==== //Wichtig: Um Inkonsistenzen bei spiegelnden Backups zu vermeiden, müssen die Datenbanken (MariaDB für Nextcloud/Ghost und Postgres für Immich) vor dem eigentlichen Datei-Backup per cron-gesteuertem Dump gesichert werden.// # Befehl für den MariaDB-Dump (Nextcloud & Ghost) im laufenden Container: docker exec nextcloud-db mysqldump -u root -p[PASSWORT] --all-databases > /opt/docker/backups/mariadb_backup.sql ===== 5. Wartung, Pflege & Best Practices ===== //Die "Spickzettel"-Sektion für wiederkehrende administrative Aufgaben im Terminal.// ==== 5.1 System-Updates ==== sudo apt update && sudo apt upgrade -y ==== 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: # 1. Haupt-Infrastruktur updaten cd /opt/docker/ docker compose pull && docker compose up -d --remove-orphans && docker image prune -a # 2. Immich Foto-Infrastruktur separat updaten cd /opt/docker/immich/ docker compose pull && docker compose up -d --remove-orphans && docker image prune -a === 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: 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 ~' **Wartungsbefehl im Alltag:** update-server ==== 5.3 Speicherplatz-Analyse ==== df -h du -h --max-depth=1 ==== 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.1 Nginx Proxy Manager (NPM) ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 80 (HTTP), 443 (HTTPS), 81 (Web-UI Admin) * **Externer Zugriff:** Ports 80 & 443 direkt im Router auf das TC weitergeleitet. * **Abhängigkeiten:** Keinerlei Abhängigkeiten. Das Einfallstor für alle HTTP-Dienste. === Bedienung & Wichtige Befehle === * **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 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):** rewrite ^/band-wiki(.*)$ https://band-wiki.tietge.org$1 permanent; **WG-Wiki:** * **Define Location:** ''/wg-wiki'' * **Scheme & Ziel:** ''http://192.168.178.128:8083'' * **Erweiterte Nginx-Konfiguration (Zahnrad):** rewrite ^/wg-wiki(.*)$ https://wg-wiki.tietge.org$1 permanent; **AK-Wiki:** * **Define Location:** ''/ak-wiki'' * **Scheme & Ziel:** ''http://192.168.178.128:8082'' * **Erweiterte Nginx-Konfiguration (Zahnrad):** rewrite ^/ak-wiki(.*)$ https://ak-wiki.tietge.org$1 permanent; == 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 ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 53 (DNS), 8080 (Web-UI HTTP) * **Externer Zugriff:** Rein lokal. **Niemals** Port 53 nach außen öffnen (Gefahr von DNS Amplification Attacks!). * **Abhängigkeiten:** Keine. Agiert als lokaler DNS-Server im Heimnetzwerk. === Bedienung & Wichtige Befehle === * **Web-UI:** [[http://192.168.178.200:8080/admin]] * **Fritz!Box-Eintrag:** Unter Heimnetz $\rightarrow$ Netzwerkeinstellungen $\rightarrow$ IPv4-Adressen das TC (192.168.178.200) als lokalen DNS-Server eintragen, damit alle Clients automatisch werbefrei surfen. ==== 6.3 MariaDB (Zentrale SQL-Datenbank) ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 3306 (MySQL) * **Externer Zugriff:** Rein intern über das Docker-Netzwerk ''server-network''. * **Abhängigkeiten:** Basis-Datenbank für Nextcloud und Ghost-CMS. === Besonderheiten & Fehlerbehebung === * **Tuning (UTF8mb4):** Startparameter in Compose erzwingen ''--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci'', da Ghost sonst die Tabellenerstellung verweigert. Liegt zwingend auf der schnellen NVMe. ==== 6.4 Redis Cache ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 6379 (In-Memory Key-Value) * **Externer Zugriff:** Isoliert im Docker-Netzwerk. * **Abhängigkeiten:** Geteilter Cache für Nextcloud, Immich und Paperless-ngx zur extremen Einsparung von RAM-Ressourcen. ==== 6.5 Nextcloud (Familien-Zentrale) ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 80 (HTTP im Container) * **Externer Zugriff:** Über NPM auf Subdomain ''nextcloud.tietge.org''. * **Abhängigkeiten:** Benötigt ''nextcloud-db'' und ''nextcloud-redis''. === Besonderheiten & Troubleshooting === * **Pfad-Trennung:** App-Code und Konfigurationen liegen auf der NVMe. Die eigentlichen Benutzerdaten liegen auf der externen HDD1 (''PATH_HDD''). * **Obsidian-Sync über WebDAV:** Für das Obsidian-Plugin ''Remotely Save'' wird folgender WebDAV-Pfad auf PC und Android hinterlegt: ''https://nextcloud.tietge.org/remote.php/dav/files/[user]/[pfad]'' ==== 6.6 DokuWiki-Instanzen (Band, AK, WG) ==== === Installation & Protokoll === * **Interne Ports / Host-Ports:** 8081 (''band-wiki''), 8082 (''ak-wiki''), 8083 (''wg-wiki'') * **Externer Zugriff:** NPM-Routing über die jeweiligen Subdomains (''projekt.tietge.org'', ''wiki.tietge.org'', ''archiv.tietge.org''). * **Abhängigkeiten:** Keine (DokuWiki nutzt ein Flat-File-System). === Besonderheiten & Rechteverwaltung === Durch die Nutzung der ''linuxserver.io''-Images werden Dateirechte-Konflikte über die übergebenen Umgebungsvariablen ''PUID=1000'' und ''PGID=1000'' systemseitig abgefangen. Alle Konfigurationen, Seiten und Plugins liegen konsistent auf der schnellen NVMe unter ''${PATH_SSD}/[wiki-name]/config''. ==== 6.7 Home Assistant ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 8123 (HTTP) * **Externer Zugriff:** Über NPM gesichert (Subdomain). * **Abhängigkeiten:** Gekoppelt mit Mosquitto MQTT. === Besonderheiten & Tuning === * **NVMe-Entlastung:** Die extrem schreibintensive Recorder-Datenbank (''home-assistant_v2.db'') wird gezielt über ein Volume auf die **SATA-SSD** umgebogen, um die System-NVMe von permanenten Sensor-Schreibzyklen zu befreien. Der Zigbee/Z-Wave Stick wird direkt per ''devices''-Flag durchgereicht (Kein unsicheres ''--privileged'' nötig). ==== 6.8 Mosquitto MQTT Broker ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 1883 (MQTT), 9001 (Websockets) * **Externer Zugriff:** Nur lokal für IoT-Geräte und ESPHome-Sensoren. * **Abhängigkeiten:** Smart-Home-Schnittstelle zu Home Assistant. ==== 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 === * **Interner Port / Protokoll:** 8000 (Auf Host-Port 8090 gemappt) * **Web-UI lokal:** [[http://192.168.178.200:8090]] (bzw. während der Migration [[http://192.168.178.128:8090]]) * **Abhängigkeiten:** Nutzt den dedizierten, isolierten ''paperless-redis''-Container zur Vermeidung von Cache-Überschneidungen mit Nextcloud. === Besonderheiten & Pfadtrennung === Das System nutzt ein dreistufiges Mapping zur optimalen Performanceverteilung: - **NVMe SSD:** Server-Konfigurationen und App-Daten (''/usr/src/paperless/data''). - **SATA-SSD (Stoßdämpfer):** Schreibintensiver, permanenter Suchindex sowie der ''consume''-Ordner für das Datei-Scanning (''/usr/src/paperless/consume''). - **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) === Da der FTP-Server den Brother-Scanner zwingend im Linux-Home-Verzeichnis (''/home/matthias/'') einsperrt, leiten Linux-Bind-Mounts die Scans in Echtzeit auf den Docker-Schnittpunkt der SATA-SSD um. # Verzeichnisstruktur auf dem Ziel-Medium (SATA-SSD) sudo mkdir -p /mnt/sata-ssd/paperless/consume/matthias sudo mkdir -p /mnt/sata-ssd/paperless/consume/jana sudo mkdir -p /mnt/sata-ssd/paperless/consume/gemeinsam sudo chown -R matthias:matthias /mnt/sata-ssd/paperless/ # Physische Verzeichnisstruktur im FTP-Homeverzeichnis mkdir -p /home/matthias/scan-matthias mkdir -p /home/matthias/scan-jana mkdir -p /home/matthias/scan-gemeinsam Dauerhafte Einhängung am Ende der ''/etc/fstab'': /mnt/sata-ssd/paperless/consume/matthias /home/matthias/scan-matthias none bind 0 0 /mnt/sata-ssd/paperless/consume/jana /home/matthias/scan-jana none bind 0 0 /mnt/sata-ssd/paperless/consume/gemeinsam /home/matthias/scan-gemeinsam none bind 0 0 //Tipp für HDD-Migration: Bei einem späteren Wechsel auf die 4TB HDDs müssen in der fstab lediglich die linken Quellpfade von /mnt/sata-ssd/... auf das HDD-Verzeichnis angepasst werden.// === Scanner-Konfiguration (Brother ADS-1800W) === In der Weboberfläche des Scanners müssen die Pfade zwingend **relativ** (ohne führende oder abschließende Slashes!) angegeben werden: * **Profil Matthias:** Zielordner: ''scan-matthias'' | SSL/TLS: ''Nichts'' * **Profil Jana:** Zielordner: ''scan-jana'' | SSL/TLS: ''Nichts'' * **Profil Gemeinsam:** Zielordner: ''scan-gemeinsam'' | SSL/TLS: ''Nichts'' === Multi-User-Workflows & Speicherpfade === ^ Typ ^ Name / Filter ^ Aktion: Eigentümer ^ Aktion: Speicherpfad ^ | **Speicherpfad** | Matthias | - | %%matthias/{created_year}/{correspondent}/{title}%% | | **Speicherpfad** | Jana | - | %%jana/{created_year}/{correspondent}/{title}%% | | **Speicherpfad** | Gemeinsam | - | %%gemeinsam/{created_year}/{correspondent}/{title}%% | | **Arbeitsablauf** | Zuweisung Matthias (Filter: %%**/matthias/*%%) | %%matthias%% | %%Matthias%% | | **Arbeitsablauf** | Zuweisung Jana (Filter: %%**/jana/*%%) | %%jana%% | %%Jana%% | | **Arbeitsablauf** | Zuweisung Gemeinsam (Filter: %%**/gemeinsam/*%%) | Berechtigung beide | %%Gemeinsam%% | //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) ==== Selbstgehostete Foto- und Videoplattform als performanter Ersatz für Google Photos. === Installation & Protokoll === * **Interner Port/Protokoll:** 2283 (HTTP) * **Lokale Web-UI:** http://192.168.178.128:2283/ * **Externer Zugriff:** Über NPM Proxy Host mit aktiven Websockets und ''client_max_body_size 512M;'' * **Abhängigkeiten:** Nutzt eine isolierte PostgreSQL-Datenbank mit Vektorerweiterung (''pgvecto-rs'') und teilt sich den zentralen Redis-Cache. === 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) == 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! == 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. 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 === 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: # 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" == 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: cd /opt/docker/immich && docker compose down 2. Daten per ''rsync'' auf die HDD migrieren: sudo rsync -avzP /mnt/sata-ssd/immich/original-media/ /media/usbhdd1/ocdata/immich/ 3. Pfad in der ''/opt/docker/immich/.env'' anpassen und Stack starten: # Neue Zuweisung in der .env: UPLOAD_LOCATION=/media/usbhdd1/ocdata/immich # Start: docker compose up -d ==== 6.11 Ghost (CMS für die Porgys) ==== === Installation & Protokoll === * **Interner Port / Protokoll:** 2368 (Auf Host-Port 8084 gemappt) * **Externer Zugriff:** NPM Proxy Host für die Band-Domain (z.B. ''porgys.de'' oder ''tpfos.de''). * **Abhängigkeiten:** Nutzt die geteilte, zentrale MariaDB (''nextcloud-db''). === Vorbereitung vor Erststart === Bevor der Container hochgefahren werden kann, muss in der zentralen MariaDB manuell eine leere Datenbank und der passende User angelegt werden: CREATE DATABASE ghost_prod; CREATE USER 'ghost_user'@'%' IDENTIFIED BY 'GhostMariaDbPasswort999!'; GRANT ALL PRIVILEGES ON ghost_prod.* TO 'ghost_user'@'%'; FLUSH PRIVILEGES; 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''. 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 === 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''. 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 === 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.1 Brother ADS-1800W Konfiguration ==== * **Web-UI:** [[https://192.168.178.127/|https://192.168.178.127/]] * **Admin-Passwort:** ''haopupsers'' //(Hinweis: Nicht in KeePass dokumentiert, da rein lokaler Gerätezugriff)// === 7.1.1 FTP-Profile (Scanner-Weboberfläche) === Die Pfade in der Weboberfläche des Scanners müssen zwingend **relativ** (ohne führende oder abschließende Slashes!) angegeben werden, damit sie sauber im Samba-/FTP-Share des Servers auflösen: * **Profil Matthias:** Zielordner: ''scan-matthias'' | SSL/TLS: ''Nichts'' * **Profil Jana:** Zielordner: ''scan-jana'' | SSL/TLS: ''Nichts'' * **Profil Gemeinsam:** Zielordner: ''scan-gemeinsam'' | SSL/TLS: ''Nichts'' ==== 7.2 Multi-User-Workflows & Speicherpfade ==== === 7.2.1 Logische Speicherpfade (Paperless-ngx) === In Paperless angelegte Pfad-Strukturen für die finale Dateiablage auf dem Speichermedium: ^ Typ ^ Name ^ Aktion: Speicherpfad ^ | Speicherpfad | Matthias | ''matthias/{created_year}/{correspondent}/{title}'' | | Speicherpfad | Jana | ''jana/{created_year}/{correspondent}/{title}'' | | Speicherpfad | Gemeinsam | ''gemeinsam/{created_year}/{correspondent}/{title}'' | === 7.2.2 Automatisierte Arbeitsabläufe (Workflows) === **Wichtig für die Fehlerfreiheit:** Um den physischen Eingangsordner des Docker-Containers zuverlässig abzugreifen, darf //nicht// der Auslösertyp "Dokument hinzugefügt" verwendet werden (dieser verwirft die Pfad-Metadaten). Stattdessen muss zwingend **"Verarbeitung gestartet"** genutzt werden, um das Feld **"Pfad filtern"** freizuschalten. ^ Name / Auslöser ^ Auslösertyp ^ Pfad filtern ^ Aktion: Eigentümer ^ Aktion: Speicherpfad ^ | **Zuweisung Matthias** | Verarbeitung gestartet | ''*/matthias/*'' | ''matthias'' (Privat) | Matthias | | **Zuweisung Jana** | Verarbeitung gestartet | ''*/jana/*'' | ''jana'' (Privat) | Jana | | **Zuweisung Gemeinsam** | Verarbeitung gestartet | ''*/gemeinsam/*'' | ''matthias'' //(oder jana)// | Gemeinsam //(+ Gruppe "Familie" RW-Rechte)// | > **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.1 Verbindungs-Timeouts bei großen Dokumenten === Sollten mehrseitige Scans (z. B. ab 8 Seiten) im Log abbrechen oder unvollständig verarbeitet werden, liegt dies an zu kurzen Timeout-Zeiten in der Netzwerkschnittstelle zwischen Scanner und Docker-Container. * **Lösung:** Den FTP/Netzwerk-Timeout im Brother-Web-UI oder der Docker-Compose-Umgebung hochsetzen. Ein fehlerfreier Durchlauf von 8 Seiten benötigt ca. 60–70 Sekunden Verarbeitungszeit (inkl. Tesseract OCR-Inhaltsanalyse). === 7.3.2 Berechtigungen bei App-Login-Fehlern (403 Forbidden) === Wenn der Login über Drittanbieter-Apps (z. B. ''Paperless Mobile'' für Android oder ''Swift Paperless'' für iOS) mit dem Admin-Konto funktioniert, aber mit dem persönlichen Benutzerkonto fehlschlägt, fehlen im Backend die Django-Berechtigungen. * **Lösung:** Über den Browser als globaler Admin anmelden -> ''Einstellungen -> Benutzer & Gruppen'' -> Benutzer auswählen. * **Status:** Haken setzen bei **"Status: Ist Mitarbeiter"** (Is staff status). Ohne diesen Haken wird der API-Zugriff blockiert. * **Berechtigungen:** Für den Alltagsgebrauch müssen der Tabelle mindestens Rechte für ''Document (Alle)'', ''Tag (Alle)'', ''Correspondent (Alle)'', ''SavedView (Alle)'' und ''UISettings (Alle)'' zugewiesen werden.