# Media Server Dashboard Statisches Homelab-Dashboard mit Live-Speicheranzeige für einen gemounteten Pfad (`/downloads`). Die Weboberfläche listet Media-Server-Dienste als Kacheln und zeigt den aktuellen Speicherplatz des Download-Laufwerks an. ## Übersicht | Komponente | Aufgabe | |---|---| | **nginx** | Liefert die statische Website (`index.html`) und die Datei `disk.json` aus | | **diskinfo** | Liest per `df` den Speicher des gemounteten Pfads und schreibt alle 30 Sekunden `disk.json` | | **Browser** | Lädt `disk.json` per Javalescript und aktualisiert die Speicheranzeige | ``` ┌─────────────┐ GET /disk.json ┌─────────────┐ │ Browser │ ◄────────────────────── │ nginx │ └─────────────┘ │ (Port 80) │ └──────▲──────┘ │ liest /opt/nginx/html/disk.json ▲ │ schreibt alle 30s ┌──────┴──────┐ │ diskinfo │ │ (alpine) │ └──────┬──────┘ │ df -h /mnt/ssd → /downloads ``` ## Projektstruktur ``` . ├── docker-compose.yml # Container-Definition (nginx + diskinfo) ├── html/ │ ├── index.html # Dashboard (Apps + Speicheranzeige) │ ├── disk.json # Wird vom diskinfo-Container geschrieben │ ├── filebot-media-browser.svg │ ├── redirect.html │ └── bk_index.htm # Backup der alten index.html └── scripts/ └── update-disk.sh # Speicher auslesen + Endlosschleife ``` ## Voraussetzungen - Docker und Docker Compose auf dem Host - Gemounteter Speicherpfad auf dem Host (Standard: `/mnt/ssd`) - Port 80 frei ## Deployment ### 1. Dateien auf den Server kopieren Auf dem Server liegt das Projekt typischerweise unter `/opt/nginx`: ```bash /opt/nginx/ ├── docker-compose.yml ├── html/ └── scripts/ └── update-disk.sh ``` Dateien aus diesem Repository dorthin kopieren, z. B. per `git clone`, `rsync` oder `scp`. Alternativ kann `update-disk.sh` direkt auf dem Server angelegt werden: ```bash cat > /opt/nginx/scripts/update-disk.sh << 'EOF' #!/bin/sh MOUNT="/downloads" OUTPUT="/html/disk.json" update_disk() { LINE=$(df -h "$MOUNT" 2>/dev/null | awk 'NR==2') if [ -z "$LINE" ]; then echo "ERROR: df failed for $MOUNT" >&2 return 1 fi TOTAL=$(echo "$LINE" | awk '{print $2}') USED=$(echo "$LINE" | awk '{print $3}') AVAILABLE=$(echo "$LINE" | awk '{print $4}') USE_PERCENT=$(echo "$LINE" | awk '{print $5}') cat > "$OUTPUT" < ... << 'EOF'` direkt auf dem Server anlegen, dann Container neu erstellen: ```bash docker compose up -d --force-recreate diskinfo ``` ### `disk.json` bleibt bei 93 Bytes / alte Werte - Altes JSON-Format ohne `updated_at` → Skript auf dem Server ist veraltet - Neues Format ist ca. 130+ Bytes groß ### Speicheranzeige zeigt „Fehler“ ```bash # Mount im Container prüfen docker compose exec diskinfo df -h /downloads # Schreibrechte prüfen docker compose exec diskinfo sh -c 'touch /html/test && rm /html/test && echo OK' ``` ### `diskinfo` zeigt `ERROR: df failed for /downloads` - Host-Pfad `/mnt/ssd` existiert nicht oder ist nicht gemountet - Volume-Mapping in `docker-compose.yml` prüfen ### Nginx liefert `disk.json`, Werte ändern sich aber nicht 1. `docker compose ps diskinfo` → Status muss `Up` sein (nicht `Restarting`) 2. `docker compose logs diskinfo` → regelmäßige `disk.json updated`-Zeilen 3. `watch -n 5 cat /opt/nginx/html/disk.json` → `updated_at` muss sich ändern ## Wartung ```bash # Container neu starten docker compose restart # Nur diskinfo neu erstellen (nach Skript-Update) docker compose up -d --force-recreate diskinfo # Logs anzeigen docker compose logs -f # Container stoppen docker compose down ``` ## Bekannte Einschränkungen - Die Speicheranzeige bezieht sich auf das **Filesystem des Mounts**, nicht auf den Inhalt eines Unterordners - nginx mountet `/downloads` nur lesend; Schreibzugriff erfolgt ausschließlich über `diskinfo` auf `/html` - Service-Status (grüner Punkt) nutzt `fetch` mit `no-cors` und kann je nach Browser/Dienst ungenau sein - Apple Touch Icons (`apple-touch-icon.png` etc.) sind nicht vorhanden → 404 in den nginx-Logs (harmlos)