Linux-use: Unterschied zwischen den Versionen
Admin (Diskussion | Beiträge) Markierungen: Manuelle Zurücksetzung Visuelle Bearbeitung |
|||
| (85 dazwischenliegende Versionen von 12 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
= STORE2 NETZWERK-ARCHITEKTUR - KURZREFERENZ = | |||
== KRITISCHE ARCHITEKTUR-GRUNDLAGEN == | |||
'''Drei parallele Zugriffswege:''' | |||
# Apache Reverse Proxy (Port 443/80) → Domain <code>dergagi.changeip.org</code> | |||
# Traefik Reverse Proxy (Port 8444/81) → Nextcloud <code>nc.dergagi9.duckdns.org:8444</code> | |||
# Direkte HTTP-Ports → Dienste ohne Proxy | |||
== APACHE VIRTUALHOST STRUKTUR (PORT 443) == | |||
'''Zwei VirtualHosts auf Port 443:''' | |||
* <code>000-catchall-443.conf</code> (ServerName: catchall.local, ''default'') | |||
* <code>000-website-dergagi-443.conf</code> (ServerName: dergagi.changeip.org) | |||
'''KRITISCH:''' Beide VirtualHosts haben identische ProxyPass-Regeln, weil catchall als Default viele Requests abfängt. | |||
'''Aktive ProxyPass-Routen:''' | |||
<code>/w/ → <nowiki>http://127.0.0.1:8088</nowiki> (MediaWiki, Docker) | |||
/yt4k/ → <nowiki>http://127.0.0.1:8443</nowiki> (YT4K, SystemD) | |||
/ombi/ → <nowiki>http://127.0.0.1:3579/ombi/</nowiki> (Ombi, Docker) | |||
/cwa → <nowiki>http://127.0.0.1:8084</nowiki> (Calibre-Web, Docker) | |||
/api → <nowiki>http://127.0.0.1:8443/api</nowiki></code> | |||
'''Port 444:''' Home Assistant Proxy → <code><nowiki>http://127.0.0.1:8123</nowiki></code> | |||
== KRITISCHE ERKENNTNISSE (LESSONS LEARNED) == | |||
=== 1. conf-enabled Dateien sind gefährlich === | |||
'''Problem:''' <code>/etc/apache2/conf-enabled/yt4k-*.conf</code> überschrieb VirtualHost-Configs mit alten Ports. '''Lösung:''' ALLE Proxy-Regeln direkt in VirtualHosts definieren, KEINE separaten conf-Dateien verwenden. | |||
=== 2. Apache reload ist unzuverlässig === | |||
'''Bei ProxyPass-Änderungen:''' <code>systemctl restart apache2</code> (nicht reload!) '''Grund:''' reload cached manchmal alte Backend-Ports. | |||
=== 3. SystemD Override-Dateien prüfen === | |||
'''Prüfen mit:''' <code>systemctl cat service.service</code> '''YT4K Beispiel:''' Override in <code>/etc/systemd/system/yt4k.service.d/90-force.conf</code> änderte Port auf 8443. | |||
=== 4. Backup-Dateien aus sites-enabled entfernen === | |||
Dateien wie <code>.bak</code>, <code>.tmp</code>, <code>.new</code> werden von Apache gelesen und verursachen Konflikte. | |||
== WICHTIGSTE DIENSTE & PORTS == | |||
'''Über Apache Proxy (HTTPS):''' | |||
* MediaWiki: <code><nowiki>https://dergagi.changeip.org/w/</nowiki></code> | |||
* YT4K: <code><nowiki>https://dergagi.changeip.org/yt4k/</nowiki></code> | |||
* Ombi: <code><nowiki>https://dergagi.changeip.org/ombi/</nowiki></code> | |||
'''Direkt HTTP (ohne Proxy):''' | |||
* Emby: <code><nowiki>http://dergagi.changeip.org:8096</nowiki></code> | |||
* n8n: <code><nowiki>http://dergagi.changeip.org:5678</nowiki></code> | |||
* Grafana: <code><nowiki>http://dergagi.changeip.org:3000</nowiki></code> | |||
* HomeBox: <code><nowiki>http://dergagi.changeip.org:3100</nowiki></code> | |||
* Koel: <code><nowiki>http://dergagi.changeip.org:6680</nowiki></code> | |||
* Uptime Kuma: <code><nowiki>http://dergagi.changeip.org:3001</nowiki></code> | |||
'''Traefik (Nextcloud):''' | |||
* Nextcloud: <code><nowiki>https://nc.dergagi9.duckdns.org:8444</nowiki></code> | |||
== TROUBLESHOOTING ESSENTIALS == | |||
=== 503 Service Unavailable über Apache Proxy === | |||
'''Diagnose:''' | |||
bash | |||
<code>''# Backend läuft?'' | |||
systemctl status yt4k.service | |||
ss -tlnp | grep :8443 | |||
''# Backend direkt erreichbar?'' | |||
curl <nowiki>http://127.0.0.1:8443/</nowiki> | |||
''# Apache Config korrekt?'' | |||
grep "ProxyPass.*yt4k" /etc/apache2/sites-enabled/*.conf | |||
''# Alte conf-enabled Dateien?'' | |||
ls /etc/apache2/conf-enabled/ | grep yt4k</code> | |||
'''Lösung:''' | |||
bash | |||
<code>''# Alte conf-enabled deaktivieren'' | |||
a2disconf yt4k.conf | |||
systemctl restart apache2 ''# RESTART!''</code> | |||
=== Browser erzwingt HTTPS für HTTP-Ports === | |||
'''Ursache:''' HSTS im Browser-Cache '''Lösung Chrome:''' <code>chrome://net-internals/#hsts</code> → Domain <code>dergagi.changeip.org</code> löschen '''Alternative:''' Private/Incognito Mode | |||
=== Apache Config Änderungen === | |||
'''Checkliste:''' | |||
# Backup: <code>cp config.conf config.conf.backup-$(date +%Y%m%d)</code> | |||
# Änderung vornehmen | |||
# Test: <code>apache2ctl configtest</code> | |||
# '''RESTART:''' <code>systemctl restart apache2</code> (nicht reload!) | |||
# Dienst testen: <code>curl -k <nowiki>https://dergagi.changeip.org/path/</nowiki></code> | |||
== SYSTEMD SERVICES (NATIVE/PYTHON) == | |||
'''YT4K Upscaler:''' | |||
* Port: 8443 (NICHT 8010!) | |||
* Service: <code>yt4k.service</code> | |||
* Path: <code>/srv/yt4k/</code> | |||
* User: www-data | |||
'''n8n:''' | |||
* Port: 5678 | |||
* Service: <code>n8n.service</code> | |||
* Path: <code>/opt/n8n/</code> | |||
* User: gagi | |||
'''Emby:''' | |||
* Port: 8096 | |||
* Service: <code>emby-server.service</code> | |||
* Path: <code>/opt/emby-server/</code>, <code>/var/lib/emby/</code> | |||
* User: emby | |||
'''Heatmap:''' | |||
* Port: 8020 | |||
* Service: <code>heatmap8020.service</code> | |||
* Path: <code>/opt/heatmap8020/</code> | |||
* User: root | |||
== DOCKER WICHTIGSTE CONTAINER == | |||
'''Host Network (direkt):''' | |||
* homeassistant (Port 8123) | |||
* grafana-system (Port 3000) | |||
* prometheus-system (Port 9090) | |||
'''Bridge mit Port-Mapping:''' | |||
* nextcloud-app (8086:80, über Traefik 8444) | |||
* mediawiki (8088:80) | |||
* koel (6680:80) | |||
* ombi (3579:3579) | |||
* uptime-kuma (3001:3001) | |||
'''Traefik + Nextcloud:''' | |||
* Netzwerk: <code>proxy</code> (172.27.0.0/16) | |||
* traefik-nc: Port 8444 (HTTPS), 81 (HTTP), 8082 (Dashboard) | |||
* nextcloud-app: In zwei Netzwerken (<code>proxy</code> + <code>nextcloud_nextcloud-net</code>) | |||
== SSL/TLS ZERTIFIKATE == | |||
'''Apache (Certbot):''' | |||
* Domain: <code>dergagi.changeip.org</code> | |||
* Path: <code>/etc/letsencrypt/live/dergagi.changeip.org/</code> | |||
* Gültig bis: 29.12.2025 | |||
'''Traefik (ACME):''' | |||
* Domain: Wildcard <code>*.dergagi9.duckdns.org</code> | |||
* Path: <code>/srv/traefik/letsencrypt/acme.json</code> | |||
* Gültig bis: 18.11.2025 | |||
== WICHTIGE PFADE == | |||
<code>Apache Configs: /etc/apache2/sites-enabled/ | |||
Apache Logs: /var/log/apache2/error.log | |||
Docker Compose: /srv/*/docker-compose.yml | |||
SystemD Services: /etc/systemd/system/*.service | |||
Backups: /mnt/nvme_backup/ (21 Versionen) | |||
Archive: /root/apache-archive-*/</code> | |||
== QUICK REFERENCE COMMANDS == | |||
bash | |||
<code>''# Apache'' | |||
apache2ctl configtest && systemctl restart apache2 | |||
apache2ctl -S ''# VirtualHosts anzeigen'' | |||
''# Port prüfen'' | |||
ss -tlnp | grep :PORT | |||
curl <nowiki>http://127.0.0.1:PORT/</nowiki> | |||
''# Docker'' | |||
docker ps | |||
docker logs -f CONTAINER | |||
docker compose restart | |||
''# SystemD'' | |||
systemctl status SERVICE | |||
systemctl cat SERVICE ''# Inkl. Overrides!'' | |||
journalctl -u SERVICE -f</code> | |||
== REGELN FÜR ÄNDERUNGEN == | |||
# '''NIE''' conf-enabled Dateien für Proxies verwenden | |||
# '''IMMER''' ProxyPass in beiden VirtualHosts (catchall + website) definieren | |||
# '''IMMER''' <code>systemctl restart apache2</code> bei Proxy-Änderungen (nicht reload) | |||
# '''IMMER''' <code>systemctl cat</code> prüfen bei SystemD-Services (Override-Dateien!) | |||
# '''IMMER''' Backend direkt testen bevor Proxy konfiguriert wird | |||
== HSTS-HINWEIS == | |||
'''Aktuell:''' KEIN HSTS-Header aktiv (bewusst deaktiviert) '''Grund:''' Flexible Nutzung von HTTP-Ports (3000, 5678, 6680, etc.) '''Wenn Browser HTTPS erzwingt:''' Browser-Cache löschen (siehe Troubleshooting) | |||
----'''Version:''' 1.0 Kurzfassung | '''Datum:''' 01.10.2025 | '''Basis:''' Vollständige Dokumentation v1.0 | |||
= STORE2 NETZWERK-ARCHITEKTUR DOKUMENTATION Vollständig = | |||
'''Version: 1.0 | Datum: 01.10.2025 | Host: STORE2 (Debian 13 Cinnamon)''' | |||
---- | |||
== EXECUTIVE SUMMARY == | |||
STORE2 betreibt eine hybride Infrastruktur mit '''drei parallelen Zugriffswegen''', die sorgfältig getrennt sein müssen: | |||
# '''Apache Reverse Proxy (Port 443/80)''' → Hauptdomain <code>dergagi.changeip.org</code> | |||
# '''Traefik Reverse Proxy (Port 8444/81)''' → Nextcloud <code>nc.dergagi9.duckdns.org:8444</code> | |||
# '''Direkte Port-Zugriffe''' → Dienste ohne Proxy (HTTP) | |||
Die Komplexität entsteht durch die Kombination aus: | |||
* 2 Apache VirtualHosts auf Port 443 (catchall + named) | |||
* Docker-basierte Dienste (24 Container) | |||
* SystemD-Services (4 native/Python-Apps) | |||
* Zwei separate Let's Encrypt Systeme (Apache/Certbot + Traefik/ACME) | |||
'''Kritische Erkenntnis aus heutigem Troubleshooting:''' Globale Apache <code>conf-enabled</code> Dateien überschreiben VirtualHost-Konfigurationen. Proxy-Routen müssen direkt in VirtualHosts definiert werden, NICHT in separaten conf-Dateien. | |||
---- | |||
== 1. NETZWERK-ARCHITEKTUR ÜBERSICHT == | |||
=== 1.1 Die drei Zugriffswege === | |||
<code>Internet | |||
| | |||
|-- Port 443/80 --> Apache --> Reverse Proxy --> Interne Dienste | |||
| | |||
|-- Port 8444 --> Traefik --> Nextcloud (Port 8086) | |||
| | |||
|-- Direkte Ports (3000, 5678, 6680, 8092, etc.) --> HTTP-Dienste</code> | |||
=== 1.2 Apache VirtualHost Struktur (Port 443) === | |||
Apache nutzt '''zwei VirtualHosts''', die beide auf Port 443 lauschen: | |||
'''A) 000-catchall-443.conf''' (Default VirtualHost) | |||
* ServerName: <code>catchall.local</code> | |||
* Funktion: Fängt Requests ohne spezifischen Host ab | |||
* ProxyPass: <code>/w/</code> (MediaWiki), <code>/yt4k/</code>, <code>/ombi/</code> | |||
* '''Problem:''' Ist als <code>*default*</code> konfiguriert, wird deshalb bevorzugt behandelt | |||
'''B) 000-website-dergagi-443.conf''' (Named VirtualHost) | |||
* ServerName: <code>dergagi.changeip.org</code> | |||
* Funktion: Expliziter Host-Match | |||
* ProxyPass: <code>/yt4k/</code>, <code>/api</code>, <code>/ombi/</code>, <code>/w/</code>, <code>/cwa</code> | |||
* Enthält zusätzlich: MediaWiki Rewrite-Rules, PHP-FPM Handler | |||
'''Wichtig:''' Beide VirtualHosts haben identische ProxyPass-Regeln für <code>/yt4k/</code> und <code>/ombi/</code>, um sicherzustellen, dass die Dienste unabhängig vom gewählten VirtualHost erreichbar sind. | |||
=== 1.3 Port 444 - Home Assistant === | |||
Separater VirtualHost auf Port 444 für Home Assistant: | |||
* URL: <code><nowiki>https://dergagi.changeip.org:444</nowiki></code> | |||
* Proxy zu: <code>localhost:8123</code> | |||
* Besonderheit: WebSocket-Support für <code>/api/websocket</code> | |||
---- | |||
== 2. DIENSTE-ÜBERSICHT == | |||
=== 2.1 Vollständige Dienste-Tabelle === | |||
=== 2.2 Port-Belegung (alle lauschenden Ports) === | |||
<code>80 Apache HTTP (Redirect zu HTTPS) | |||
81 Traefik HTTP (Let's Encrypt Challenge) | |||
443 Apache HTTPS (Hauptdomain) | |||
444 Apache HTTPS (Home Assistant) | |||
3000 Grafana System Monitoring | |||
3001 Uptime Kuma | |||
3100 HomeBox Inventar | |||
3579 Ombi (intern, Apache Proxy) | |||
5678 n8n Automation | |||
6680 Koel Music Streaming | |||
8020 Heatmap Generator | |||
8080 LibreSpeed | |||
8082 Traefik Dashboard | |||
8084 Calibre-Web (intern, Apache Proxy) | |||
8086 Nextcloud App (intern, Traefik Proxy) | |||
8087 InfluxDB (Speedtest Daten) | |||
8088 MediaWiki (intern, Apache Proxy) | |||
8092 Speedtest Tracker | |||
8096 Emby Media Server | |||
8123 Home Assistant (intern, Apache Proxy Port 444) | |||
8443 YT4K Upscaler (intern, Apache Proxy) | |||
8444 Traefik HTTPS (Nextcloud) | |||
9000 Portainer (nur Tailscale + localhost) | |||
9090 Prometheus System | |||
9100 Node Exporter | |||
19998 Netdata</code> | |||
---- | |||
== 3. APACHE REVERSE PROXY SETUP == | |||
=== 3.1 Haupt-Konfigurationsdateien === | |||
'''Aktive sites-enabled:''' | |||
<code>000-catchall-443.conf → Default VirtualHost, Port 443 | |||
000-website-dergagi-443.conf → Named VirtualHost, Port 443 | |||
00-redirect-80.conf → HTTP zu HTTPS Redirect | |||
homeassistant-444.conf → Home Assistant, Port 444 | |||
le-webroot-80.conf → Let's Encrypt Webroot</code> | |||
'''Wichtig:''' Keine conf-enabled Dateien mehr aktiv! Alle Proxy-Regeln sind direkt in den VirtualHosts definiert. | |||
=== 3.2 Apache Proxy-Routen (Port 443) === | |||
'''000-catchall-443.conf ProxyPass-Regeln:''' | |||
apache | |||
<code>ProxyPass /w/ <nowiki>http://127.0.0.1:8088/</nowiki> | |||
ProxyPassReverse /w/ <nowiki>http://127.0.0.1:8088/</nowiki> | |||
ProxyPass /yt4k/ <nowiki>http://127.0.0.1:8443/</nowiki> retry=0 | |||
ProxyPassReverse /yt4k/ <nowiki>http://127.0.0.1:8443/</nowiki> | |||
ProxyPass /ombi/ <nowiki>http://127.0.0.1:3579/ombi/</nowiki> retry=0 | |||
ProxyPassReverse /ombi/ <nowiki>http://127.0.0.1:3579/ombi/</nowiki></code> | |||
'''000-website-dergagi-443.conf ProxyPass-Regeln:''' | |||
apache | |||
<code>ProxyPass /api <nowiki>http://127.0.0.1:8443/api</nowiki> retry=0 | |||
ProxyPassReverse /api <nowiki>http://127.0.0.1:8443/api</nowiki> | |||
ProxyPass /yt4k/ <nowiki>http://127.0.0.1:8443/</nowiki> retry=0 | |||
ProxyPassReverse /yt4k/ <nowiki>http://127.0.0.1:8443/</nowiki> | |||
ProxyPass /ombi/ <nowiki>http://127.0.0.1:3579/ombi/</nowiki> retry=0 | |||
ProxyPassReverse /ombi/ <nowiki>http://127.0.0.1:3579/ombi/</nowiki> | |||
ProxyPass /w/ <nowiki>http://127.0.0.1:8088/</nowiki> | |||
ProxyPassReverse /w/ <nowiki>http://127.0.0.1:8088/</nowiki> | |||
<Location /cwa> | |||
ProxyPass <nowiki>http://127.0.0.1:8084/</nowiki> | |||
ProxyPassReverse <nowiki>http://127.0.0.1:8084/</nowiki> | |||
</Location></code> | |||
'''Zusätzliche Features:''' | |||
* MediaWiki Short URLs: <code>/wiki/</code> → <code>/w/index.php?title=</code> | |||
* PHP-FPM Handler für <code>.php</code> Dateien | |||
* Security Headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy) | |||
* '''Kein HSTS-Header''' (bewusst deaktiviert für flexible Port-Nutzung) | |||
=== 3.3 SSL/TLS Konfiguration (Apache) === | |||
'''Zertifikat:''' <code>/etc/letsencrypt/live/dergagi.changeip.org/</code> | |||
* Typ: Let's Encrypt (via Certbot) | |||
* Ausgestellt: 30. September 2025 | |||
* Gültig bis: 29. Dezember 2025 | |||
* Erneuerung: Automatisch via Certbot | |||
'''SSL-Engine:''' | |||
apache | |||
<code>SSLEngine on | |||
SSLCertificateFile /etc/letsencrypt/live/dergagi.changeip.org/fullchain.pem | |||
SSLCertificateKeyFile /etc/letsencrypt/live/dergagi.changeip.org/privkey.pem</code> | |||
'''Genutzt von:''' | |||
* 000-catchall-443.conf | |||
* 000-website-dergagi-443.conf | |||
* homeassistant-444.conf | |||
---- | |||
== 4. TRAEFIK REVERSE PROXY (NEXTCLOUD) == | |||
=== 4.1 Traefik v3.5 Setup === | |||
'''Container:''' <code>traefik-nc</code> '''Image:''' <code>traefik:v3.5</code> '''Netzwerk:''' <code>proxy</code> (Bridge, 172.27.0.0/16) | |||
'''Port-Mapping:''' | |||
<code>8444 (extern) → 443 (intern) HTTPS für Nextcloud | |||
81 (extern) → 80 (intern) HTTP für Let's Encrypt Challenge | |||
8082 (extern) → 8080 (intern) Traefik Dashboard</code> | |||
=== 4.2 Nextcloud Docker Compose === | |||
'''Container:''' <code>nextcloud-app</code> '''Image:''' <code>nextcloud:31.0.9</code> '''Port:''' <code>8086:80</code> (intern) | |||
'''Netzwerke:''' | |||
* <code>nextcloud_nextcloud-net</code> (Bridge, 172.26.0.0/16) → Verbindung zur DB | |||
* <code>proxy</code> (Bridge, 172.27.0.0/16) → Verbindung zu Traefik | |||
'''Environment Variables:''' | |||
yaml | |||
<code>OVERWRITEPROTOCOL: https | |||
OVERWRITEHOST: nc.dergagi9.duckdns.org:8444 | |||
NEXTCLOUD_TRUSTED_DOMAINS: nc.dergagi9.duckdns.org:8444 | |||
TRUSTED_PROXIES: 172.16.0.0/12 192.168.0.0/16 10.0.0.0/8</code> | |||
'''Traefik Labels:''' | |||
yaml | |||
<code>traefik.enable: true | |||
traefik.http.routers.nextcloud.rule: Host(`nc.dergagi9.duckdns.org`) | |||
traefik.http.routers.nextcloud.entrypoints: websecure | |||
traefik.http.routers.nextcloud.tls: true | |||
traefik.http.routers.nextcloud.tls.certresolver: letsencrypt | |||
traefik.http.services.nextcloud.loadbalancer.server.port: 80</code> | |||
=== 4.3 SSL/TLS (Traefik) === | |||
'''Zertifikat:''' Wildcard <code>*.dergagi9.duckdns.org</code> | |||
* Typ: Let's Encrypt (via Traefik ACME) | |||
* Speicherort: <code>/srv/traefik/letsencrypt/acme.json</code> | |||
* Ausgestellt: 20. August 2025 | |||
* Gültig bis: 18. November 2025 | |||
* Erneuerung: Automatisch via Traefik | |||
'''Zugriff:''' | |||
<code><nowiki>https://nc.dergagi9.duckdns.org:8444</nowiki></code> | |||
---- | |||
== 5. DOCKER CONTAINER ÜBERSICHT == | |||
=== 5.1 Container nach Netzwerk === | |||
'''Host Network (direkter Host-Zugriff):''' | |||
* <code>homeassistant</code> (Home Assistant Core) | |||
* <code>grafana-system</code> (System Monitoring, Port 3000) | |||
* <code>prometheus-system</code> (Metriken, Port 9090) | |||
* <code>node-simple</code> (Node Exporter, Port 9100) | |||
* <code>addon_5c53de3b_esphome</code> (ESPHome Add-on) | |||
* <code>addon_core_matter_server</code> (Matter Server) | |||
* <code>addon_a0d7b954_tailscale</code> (Tailscale Add-on) | |||
* <code>hassio_multicast</code> (Multicast DNS) | |||
'''Bridge Networks:''' | |||
* <code>bridge</code> (172.17.0.0/16): homebox, ombi, hassio_supervisor | |||
* <code>proxy</code> (172.27.0.0/16): traefik-nc, nextcloud-app | |||
* <code>nextcloud_nextcloud-net</code> (172.26.0.0/16): nextcloud-app, nextcloud-db | |||
* <code>koel_default</code> (172.23.0.0/16): koel, koel-db | |||
* <code>mediawiki-clean-final_default</code> (192.168.80.0/20): mw-clean-final, mw-clean-final-db | |||
* <code>cwa_default</code> (172.20.0.0/16): calibre-web-automated | |||
* <code>uptime-kuma_default</code> (192.168.32.0/20): uptime-kuma | |||
* <code>speedtest-tracker-new_default</code> (172.24.0.0/16): speedtest-tracker-new, speedtest-influxdb-v2 | |||
* <code>portainer-net</code> (192.168.160.0/20): portainer | |||
* <code>hassio</code> (172.30.32.0/23): Home Assistant Add-ons | |||
=== 5.2 Kritische Container mit Restart-Policy === | |||
Alle produktiven Container nutzen: <code>restart: unless-stopped</code> | |||
'''Ausnahmen (restart: no):''' | |||
* Home Assistant Add-ons (werden von Supervisor verwaltet) | |||
---- | |||
== 6. SYSTEMD SERVICES (NATIVE/PYTHON) == | |||
=== 6.1 Emby Media Server === | |||
'''Type:''' Native Debian Installation (Version 4.9.1.31) '''Port:''' 8096 (HTTP), 8920 (HTTPS, nicht konfiguriert) '''Service:''' <code>emby-server.service</code> '''User:''' <code>emby</code> | |||
'''Pfade:''' | |||
* Binary: <code>/opt/emby-server/</code> | |||
* Daten: <code>/var/lib/emby/</code> | |||
'''FFmpeg Override:''' | |||
<code>ExecStart=/opt/emby-server/system/EmbyServer -programdata /var/lib/emby \ | |||
-ffdetect /opt/emby-server/bin/ffdetect \ | |||
-ffmpeg /usr/bin/ffmpeg \ | |||
-ffprobe /usr/bin/ffprobe</code> | |||
=== 6.2 YT4K Upscaler (FastAPI) === | |||
'''Type:''' Python FastAPI + Uvicorn '''Port:''' 8443 (HTTP) '''Service:''' <code>yt4k.service</code> '''User:''' <code>www-data</code> '''WorkingDirectory:''' <code>/srv/yt4k/</code> | |||
'''ExecStart (via override):''' | |||
bash | |||
<code>/srv/yt4k/.venv/bin/uvicorn --app-dir /srv/yt4k app:app \ | |||
--host 0.0.0.0 --port 8443 --workers 2 --log-level info</code> | |||
'''Wichtig:''' Läuft auf <code>0.0.0.0:8443</code>, nicht auf <code>127.0.0.1:8010</code> (alte Config)! | |||
=== 6.3 n8n Automation === | |||
'''Type:''' Node.js App '''Port:''' 5678 (HTTP) '''Service:''' <code>n8n.service</code> '''User:''' <code>gagi</code> '''WorkingDirectory:''' <code>/opt/n8n/</code> | |||
'''Environment:''' | |||
<code>N8N_PORT=5678 | |||
N8N_HOST=0.0.0.0 | |||
N8N_USER_FOLDER=/opt/n8n</code> | |||
'''ExecStart:''' | |||
bash | |||
<code>/usr/local/bin/n8n</code> | |||
=== 6.4 Heatmap Generator (FastAPI) === | |||
'''Type:''' Python FastAPI + Uvicorn '''Port:''' 8020 (HTTP) '''Service:''' <code>heatmap8020.service</code> '''User:''' <code>root</code> '''WorkingDirectory:''' <code>/opt/heatmap8020/</code> | |||
'''Environment:''' | |||
<code>MPLBACKEND=Agg # Matplotlib ohne Display</code> | |||
'''ExecStart:''' | |||
bash | |||
<code>/opt/heatmap8020/.venv/bin/uvicorn app:app \ | |||
--host 0.0.0.0 --port 8020 --proxy-headers</code> | |||
---- | |||
== 7. TAILSCALE INTEGRATION == | |||
'''IP:''' <code>100.108.194.126</code> '''Hostname:''' <code>store2</code> '''Status:''' Active | |||
'''Verwendung:''' | |||
* Portainer: <code><nowiki>http://100.108.194.126:9000</nowiki></code> (einziger Zugriff) | |||
* Keine Tailscale Serve/Funnel Konfiguration aktiv | |||
'''Andere Tailscale Nodes:''' | |||
* <code>myth</code> (Windows, 100.98.212.121) - Active | |||
* <code>silvaner</code> (Windows, 100.120.162.83) - Active | |||
* Weitere Nodes offline | |||
---- | |||
== 8. MONITORING & METRICS == | |||
=== 8.1 Grafana System Monitoring === | |||
'''Container:''' <code>grafana-system</code> '''Port:''' 3000 (Host Network) '''Datenquelle:''' Prometheus System (Port 9090) | |||
'''Metriken:''' | |||
* CPU, RAM, Disk I/O via <code>node-exporter-system</code> (Port 9100) | |||
* Direkt vom Host via Host Network | |||
=== 8.2 Uptime Kuma === | |||
'''Container:''' <code>uptime-kuma</code> '''Image:''' <code>louislam/uptime-kuma:1.23.13-alpine</code> '''Port:''' 3001 '''Daten:''' <code>/opt/uptime-kuma/data</code> | |||
'''Funktion:''' | |||
* HTTP(s) Checks für alle kritischen Dienste | |||
* Ping Tests | |||
* E-Mail Alerts bei Ausfällen | |||
=== 8.3 Netdata Real-Time Monitoring === | |||
'''Type:''' Native Installation '''Port:''' 19998 '''Zugriff:''' <code><nowiki>http://dergagi.changeip.org:19998</nowiki></code> | |||
'''Metriken:''' | |||
* Real-time System Performance | |||
* Container Monitoring | |||
* Network Traffic | |||
* Disk I/O | |||
---- | |||
== 9. BACKUP & REDUNDANZ == | |||
=== 9.1 NVMe System Backup === | |||
'''Timer:''' <code>nvme-backup.timer</code> '''Schedule:''' Täglich um 03:08 Uhr '''Technologie:''' <code>rsync</code> mit <code>--link-dest</code> | |||
'''Quellen:''' System-Partitionen (NVMe) '''Ziel:''' <code>/mnt/nvme_backup</code> '''Aufbewahrung:''' 21 Versionen (Hard-Link-Snapshots) | |||
'''Wichtig:''' <code>--one-file-system</code> verhindert Backup der 113TB RAID-Arrays! | |||
=== 9.2 RAID Monitoring === | |||
'''Arrays:''' | |||
* <code>/data</code> (RAID6) | |||
* <code>/data2</code> (RAID6) | |||
'''Monitoring:''' | |||
* <code>mdadm</code> (<code>/etc/mdadm/mdadm.conf</code>) | |||
* <code>smartd</code> (<code>/etc/smartd.conf</code>) | |||
* Alert-Script: <code>/usr/local/sbin/health-alert.sh</code> | |||
'''Besonderheit:''' SMART-Fehler ID 197 (CurrentPendingSector) wird ignoriert (RAID-typisch, nicht kritisch). | |||
---- | |||
== 10. TROUBLESHOOTING GUIDE == | |||
=== 10.1 Häufige Probleme & Lösungen === | |||
==== Problem: Dienst über Apache Proxy gibt 503 Service Unavailable ==== | |||
'''Symptome:''' | |||
<code>503 Service Unavailable | |||
AH00957: http: attempt to connect to 127.0.0.1:PORT failed</code> | |||
'''Ursachen & Lösungen:''' | |||
# '''Backend läuft nicht:''' | |||
bash | |||
<code>''# Prüfen'' | |||
systemctl status yt4k.service | |||
docker ps | grep mediawiki | |||
''# Starten'' | |||
systemctl start yt4k.service | |||
docker start mw-clean-final</code> | |||
# '''Falscher Port in Apache Config:''' | |||
bash | |||
<code>''# Prüfen welcher Port tatsächlich lauscht'' | |||
ss -tlnp | grep :8443 | |||
''# Apache Config prüfen'' | |||
grep "ProxyPass.*yt4k" /etc/apache2/sites-enabled/*.conf | |||
''# Port korrigieren und neu laden'' | |||
systemctl reload apache2</code> | |||
# '''Globale conf-enabled Datei überschreibt VirtualHost:''' | |||
bash | |||
<code>''# Prüfen'' | |||
ls /etc/apache2/conf-enabled/ | |||
''# Alte yt4k-*.conf Dateien deaktivieren'' | |||
a2disconf yt4k.conf | |||
systemctl restart apache2 ''# RESTART, nicht reload!''</code> | |||
==== Problem: Browser erzwingt HTTPS für HTTP-Ports (HomeBox, Koel, n8n) ==== | |||
'''Symptome:''' | |||
<code>Browser zeigt "Sichere Verbindung fehlgeschlagen" für: | |||
<nowiki>http://dergagi.changeip.org:3100</nowiki> (HomeBox) | |||
<nowiki>http://dergagi.changeip.org:6680</nowiki> (Koel)</code> | |||
'''Ursache:''' HSTS im Browser-Cache | |||
'''Lösung:''' | |||
'''Chrome/Edge:''' | |||
# Öffne <code>chrome://net-internals/#hsts</code> | |||
# "Delete domain security policies" | |||
# Domain: <code>dergagi.changeip.org</code> | |||
# [Delete] | |||
'''Firefox:''' | |||
# <code>about:preferences#privacy</code> | |||
# "Cookies und Website-Daten" | |||
# "Daten verwalten..." | |||
# Suche: <code>dergagi.changeip.org</code> | |||
# "Ausgewählte entfernen" | |||
'''Alternative:''' Nutze Private/Incognito Mode | |||
==== Problem: MediaWiki API nicht erreichbar ==== | |||
'''Symptome:''' | |||
<code>/w/api.php gibt 404 oder wird zu falscher URL weitergeleitet</code> | |||
'''Lösung:''' | |||
bash | |||
<code>''# Prüfe RewriteRules'' | |||
grep "RewriteRule.*api.php" /etc/apache2/sites-enabled/*.conf | |||
''# Sollte sein:'' | |||
''# RewriteRule ^/w/(api\.php|load\.php|rest\.php)$ - [L]''</code> | |||
==== Problem: Nextcloud über Port 8444 nicht erreichbar ==== | |||
'''Symptome:''' | |||
<code><nowiki>https://nc.dergagi9.duckdns.org:8444</nowiki> → Connection refused</code> | |||
'''Diagnose:''' | |||
bash | |||
<code>''# Traefik läuft?'' | |||
docker ps | grep traefik-nc | |||
''# Port 8444 lauscht?'' | |||
ss -tlnp | grep :8444 | |||
''# Traefik Logs'' | |||
docker logs traefik-nc --tail 50 | |||
''# Nextcloud Container läuft?'' | |||
docker ps | grep nextcloud-app | |||
''# Netzwerk korrekt?'' | |||
docker inspect nextcloud-app | grep -A 10 Networks</code> | |||
'''Lösung:''' | |||
bash | |||
<code>cd /srv/nextcloud | |||
docker compose restart</code> | |||
=== 10.2 Apache Reload vs Restart === | |||
'''WICHTIG:''' Bei Proxy-Änderungen immer RESTART, nicht reload! | |||
bash | |||
<code>''# NUR für Header/Rewrite-Änderungen:'' | |||
systemctl reload apache2 | |||
''# Für ProxyPass-Änderungen:'' | |||
systemctl restart apache2</code> | |||
'''Grund:''' <code>reload</code> cached manchmal alte ProxyPass-Werte. | |||
=== 10.3 Docker Container Restart-Reihenfolge === | |||
Bei kompletten Neustarts (z.B. nach Server-Reboot): | |||
# Datenbank-Container zuerst: | |||
bash | |||
<code>docker start nextcloud-db mw-clean-final-db koel-db | |||
sleep 5</code> | |||
# Dann App-Container: | |||
bash | |||
<code>docker start nextcloud-app mw-clean-final koel</code> | |||
# Traefik zuletzt: | |||
bash | |||
<code>docker start traefik-nc</code> | |||
---- | |||
== 11. LESSONS LEARNED (01.10.2025) == | |||
=== 11.1 Kritische Erkenntnisse === | |||
# '''Globale conf-enabled Dateien sind gefährlich:''' | |||
#* <code>/etc/apache2/conf-enabled/yt4k-proxy-root.conf</code> überschrieb VirtualHost-Configs | |||
#* Enthielt alte Port-Nummern (8010 statt 8443) | |||
#* Wurde trotz korrekter VirtualHost-Config verwendet | |||
#* '''Best Practice:''' Alle Proxy-Regeln direkt in VirtualHosts definieren | |||
# '''Apache Reload ist nicht ausreichend:''' | |||
#* Bei ProxyPass-Änderungen: <code>systemctl restart apache2</code> | |||
#* <code>reload</code> cached manchmal alte Backend-Ports | |||
#* Führte zu 1 Stunde Debugging | |||
# '''Zwei VirtualHosts auf Port 443 = Verwirrung:''' | |||
#* <code>000-catchall-443.conf</code> als <code>*default*</code> fängt viele Requests ab | |||
#* <code>000-website-dergagi-443.conf</code> sollte eigentlich matchen | |||
#* '''Lösung:''' Beide mit identischen ProxyPass-Regeln ausstatten | |||
# '''Backup-Dateien in sites-enabled verursachen Probleme:''' | |||
#* <code>.bak</code>, <code>.tmp</code>, <code>.new</code> Dateien werden von Apache gelesen | |||
#* Können zu Konflikten führen | |||
#* '''Best Practice:''' Nur <code>.conf</code> Dateien in sites-enabled | |||
# '''SystemD Service Override-Dateien:''' | |||
#* <code>/etc/systemd/system/yt4k.service.d/90-force.conf</code> überschrieb Haupt-Service | |||
#* Port 8443 statt 8010 - aber Apache zeigte auf 8010 | |||
#* '''Immer prüfen:''' <code>systemctl cat service.service</code> | |||
=== 11.2 Erfolgreiche Strategien === | |||
# '''Systematisches Debugging:''' | |||
#* Port-Listening prüfen: <code>ss -tlnp | grep :PORT</code> | |||
#* Backend direkt testen: <code>curl <nowiki>http://127.0.0.1:PORT/</nowiki></code> | |||
#* Apache Error Log live: <code>tail -f /var/log/apache2/error.log</code> | |||
#* VirtualHost Dump: <code>apache2ctl -S</code> | |||
# '''Archivierung statt Löschen:''' | |||
#* Alle Backup-Dateien nach <code>/root/apache-archive-DATE/</code> | |||
#* Ermöglicht schnelles Rollback | |||
#* 81 alte Configs archiviert, System bleibt sauber | |||
# '''Docker Netzwerk-Isolation:''' | |||
#* Nextcloud in <code>proxy</code> + <code>nextcloud_nextcloud-net</code> | |||
#* Traefik nur in <code>proxy</code> | |||
#* Saubere Trennung zwischen Diensten | |||
---- | |||
== 12. WARTUNGS-CHECKLISTEN == | |||
=== 12.1 Vor jeder Apache-Änderung === | |||
bash | |||
<code>''# 1. Backup der aktuellen Config'' | |||
cp /etc/apache2/sites-enabled/000-website-dergagi-443.conf \ | |||
/root/000-website-dergagi-443.conf.backup-$(date +%Y%m%d-%H%M%S) | |||
''# 2. Änderung vornehmen'' | |||
''# 3. Config testen'' | |||
apache2ctl configtest | |||
''# 4. Bei Erfolg: RESTART (nicht reload)'' | |||
systemctl restart apache2 | |||
''# 5. Dienste testen'' | |||
curl -k <nowiki>https://dergagi.changeip.org/yt4k/</nowiki> | |||
curl -k <nowiki>https://dergagi.changeip.org/w/</nowiki></code> | |||
=== 12.2 Neuen Dienst über Apache proxyen === | |||
# '''Dienst starten und Port prüfen:''' | |||
bash | |||
<code>systemctl start new-service | |||
ss -tlnp | grep :PORT | |||
curl <nowiki>http://127.0.0.1:PORT/</nowiki></code> | |||
# '''ProxyPass in BEIDEN VirtualHosts hinzufügen:''' | |||
bash | |||
<code>nano /etc/apache2/sites-enabled/000-catchall-443.conf | |||
''# Füge hinzu:'' | |||
ProxyPass /newservice/ <nowiki>http://127.0.0.1:PORT/</nowiki> retry=0 | |||
ProxyPassReverse /newservice/ <nowiki>http://127.0.0.1:PORT/</nowiki> | |||
nano /etc/apache2/sites-enabled/000-website-dergagi-443.conf | |||
''# Gleiche Zeilen hinzufügen''</code> | |||
# '''Testen und Restart:''' | |||
bash | |||
<code>apache2ctl configtest | |||
systemctl restart apache2 | |||
curl -k <nowiki>https://dergagi.changeip.org/newservice/</nowiki></code> | |||
# '''NICHT in conf-enabled anlegen!''' | |||
=== 12.3 Docker Container hinzufügen === | |||
# '''docker-compose.yml erstellen:''' | |||
yaml | |||
<code>services: | |||
newservice: | |||
image: newservice:latest | |||
container_name: newservice | |||
restart: unless-stopped | |||
ports: | |||
- "PORT:INTERNAL_PORT" | |||
volumes: | |||
- ./data:/data | |||
networks: | |||
- newservice_net | |||
networks: | |||
newservice_net: | |||
driver: bridge</code> | |||
# '''Starten:''' | |||
bash | |||
<code>cd /srv/newservice | |||
docker compose up -d</code> | |||
# '''Logs prüfen:''' | |||
bash | |||
<code>docker logs newservice -f</code> | |||
=== 12.4 SSL-Zertifikat erneuern (Apache) === | |||
bash | |||
<code>''# Certbot Dry-Run'' | |||
certbot renew --dry-run | |||
''# Manuelle Erneuerung'' | |||
certbot renew | |||
''# Apache neu laden'' | |||
systemctl reload apache2 | |||
''# Zertifikat prüfen'' | |||
openssl x509 -in /etc/letsencrypt/live/dergagi.changeip.org/fullchain.pem -noout -dates</code> | |||
=== 12.5 Monatliche Wartung === | |||
bash | |||
<code>''# 1. System Updates'' | |||
apt update && apt upgrade -y | |||
''# 2. Docker Images aktualisieren'' | |||
cd /srv/nextcloud && docker compose pull && docker compose up -d | |||
cd /srv/mediawiki-clean-final && docker compose pull && docker compose up -d | |||
''# 3. Alte Docker Images entfernen'' | |||
docker image prune -a | |||
''# 4. Logs rotieren'' | |||
journalctl --vacuum-time=30d | |||
''# 5. Backup prüfen'' | |||
ls -lh /mnt/nvme_backup/ | |||
''# 6. RAID Status'' | |||
cat /proc/mdstat</code> | |||
---- | |||
== 13. DATEI-PFADE REFERENZ == | |||
=== 13.1 Apache === | |||
<code>/etc/apache2/sites-available/ Alle verfügbaren Configs | |||
/etc/apache2/sites-enabled/ Aktive Configs (Symlinks) | |||
/etc/apache2/conf-available/ Zusätzliche Configs (sollte leer sein!) | |||
/etc/apache2/conf-enabled/ Aktive zusätzliche Configs | |||
/var/log/apache2/error.log Error Log | |||
/var/log/apache2/access.log Access Log | |||
/etc/letsencrypt/live/ SSL-Zertifikate</code> | |||
=== 13.2 Docker === | |||
<code>/srv/nextcloud/ Nextcloud + Traefik | |||
/srv/mediawiki-clean-final/ MediaWiki | |||
/srv/koel/ Koel Music | |||
/srv/ombi/ Ombi | |||
/srv/portainer/ Portainer | |||
/opt/uptime-kuma/ Uptime Kuma</code> | |||
=== 13.3 SystemD Services === | |||
<code>/etc/systemd/system/yt4k.service YT4K Service | |||
/etc/systemd/system/yt4k.service.d/ YT4K Overrides | |||
/srv/yt4k/ YT4K Code + venv | |||
/etc/systemd/system/n8n.service n8n Service | |||
/opt/n8n/ n8n Daten | |||
/etc/systemd/system/heatmap8020.service Heatmap Service | |||
/opt/heatmap8020/ Heatmap Code + venv | |||
/usr/lib/systemd/system/emby-server.service Emby Service (System) | |||
/etc/systemd/system/emby-server.service.d/ Emby Overrides | |||
/opt/emby-server/ Emby Binary | |||
/var/lib/emby/ Emby Daten</code> | |||
=== 13.4 Backups & Archive === | |||
<code>/mnt/nvme_backup/ System Backups (21 Versionen) | |||
/root/apache-archive-YYYYMMDD-HHMMSS/ Alte Apache Configs | |||
/root/apache-backup-YYYYMMDD-HHMMSS/ Apache Config Backups | |||
/root/network-fix-YYYYMMDD-HHMMSS/ Troubleshooting Logs | |||
/root/apache-old-backups/ Archivierte Backups</code> | |||
---- | |||
== 14. NÄCHSTE SCHRITTE & EMPFEHLUNGEN == | |||
=== 14.1 Kurzfristig (nächste Woche) === | |||
# '''Alte Docker-Verzeichnisse aufräumen:''' | |||
bash | |||
<code>''# Prüfen und löschen (wenn nicht mehr benötigt):'' | |||
/srv/nextcloud-damaged-2025-09-03-112720 | |||
/srv/traefik-damaged-2025-09-03-113532 | |||
/srv/mw-docker.final-removal.20250831-111413 | |||
/opt/n8n.bak.2025-08-23-191443</code> | |||
# '''Apache Archive aufräumen:''' | |||
bash | |||
<code>''# Nach 1 Woche ohne Probleme:'' | |||
rm -rf /root/apache-archive-20251001-231820</code> | |||
# '''Uptime Kuma Monitoring vervollständigen:''' | |||
#* Alle Dienste als Monitors hinzufügen | |||
#* E-Mail Alerts konfigurieren | |||
=== 14.2 Mittelfristig (nächster Monat) === | |||
# '''HSTS für Port 443 aktivieren:''' | |||
#* Nachdem Browser-Cache gelöscht ist | |||
#* Nur für <code>/</code> Path, nicht global | |||
#* <code>max-age=15552000</code> (6 Monate) | |||
# '''Traefik für mehr Dienste nutzen:''' | |||
#* YT4K, Ombi, MediaWiki könnten über Traefik laufen | |||
#* Vereinfacht SSL-Management | |||
#* Automatische Let's Encrypt Erneuerung | |||
# '''000-catchall-443.conf entfernen:''' | |||
#* Alle Requests sollten explizit auf 000-website-dergagi-443.conf matchen | |||
#* Vereinfacht Konfiguration | |||
=== 14.3 Langfristig (optional) === | |||
# '''Alle Docker Compose in ein zentrales File:''' | |||
#* <code>/srv/docker-stack/docker-compose.yml</code> | |||
#* Vereinfacht Management | |||
#* Einheitliche Netzwerk-Struktur | |||
# '''Monitoring erweitern:''' | |||
#* Prometheus für alle Dienste | |||
#* Alertmanager für Benachrichtigungen | |||
#* Längere Metriken-Retention | |||
# '''Backup-Strategie für Docker Volumes:''' | |||
#* Automatische Backups für Nextcloud-Daten | |||
#* MediaWiki-Datenbank Dumps | |||
#* Offsite-Backup erwägen | |||
---- | |||
== ANHANG A: SCHNELLREFERENZ == | |||
=== Apache Befehle === | |||
bash | |||
<code>apache2ctl configtest ''# Config testen'' | |||
apache2ctl -S ''# VirtualHosts anzeigen'' | |||
apache2ctl -M ''# Module anzeigen'' | |||
systemctl restart apache2 ''# Komplett neu starten'' | |||
systemctl reload apache2 ''# Config neu laden (unsicher!)'' | |||
a2ensite site.conf ''# Site aktivieren'' | |||
a2dissite site.conf ''# Site deaktivieren'' | |||
a2enmod proxy_http ''# Modul aktivieren''</code> | |||
=== Docker Befehle === | |||
bash | |||
<code>docker ps ''# Laufende Container'' | |||
docker ps -a ''# Alle Container'' | |||
docker logs CONTAINER ''# Logs anzeigen'' | |||
docker logs -f CONTAINER ''# Logs live'' | |||
docker restart CONTAINER ''# Container neu starten'' | |||
docker compose up -d ''# Services starten'' | |||
docker compose down ''# Services stoppen'' | |||
docker compose restart ''# Services neu starten'' | |||
docker network ls ''# Netzwerke anzeigen'' | |||
docker inspect CONTAINER ''# Details anzeigen''</code> | |||
=== SystemD Befehle === | |||
bash | |||
<code>systemctl status SERVICE ''# Status prüfen'' | |||
systemctl start SERVICE ''# Service starten'' | |||
systemctl stop SERVICE ''# Service stoppen'' | |||
systemctl restart SERVICE ''# Service neu starten'' | |||
systemctl cat SERVICE ''# Config anzeigen (inkl. Overrides)'' | |||
journalctl -u SERVICE -f ''# Logs live'' | |||
journalctl -u SERVICE -n 50 ''# Letzte 50 Zeilen''</code> | |||
=== Netzwerk Debug === | |||
bash | |||
<code>ss -tlnp ''# Alle lauschenden Ports'' | |||
ss -tlnp | grep :PORT ''# Spezifischer Port'' | |||
curl <nowiki>http://127.0.0.1:PORT/</nowiki> ''# Backend direkt testen'' | |||
curl -I -k <nowiki>https://domain.com</nowiki> ''# Headers anzeigen'' | |||
netstat -tupln ''# Alternative zu ss''</code> | |||
----'''Ende der Dokumentation''' | |||
'''Letzte Aktualisierung:''' 01.10.2025, 23:30 CEST | |||
'''Version:''' 1.0 | |||
'''Erstellt von:''' Claude (Anthropic) mit Daniel Gareis | |||
'''Archiviert:''' <code>/mnt/user-data/outputs/STORE2-Network-Architecture-v1.0.md</code> | |||
= NVMe-Backup & Datenbank-Backup System - Vollständige Dokumentation v3.0 = | |||
== System-Übersicht == | |||
'''Server:''' STORE2 (Debian 13) | |||
'''Backup-Strategien:''' | |||
# '''OS-Level Backup:''' Vollständiges System-Backup via rsync + Hard Links | |||
# '''Datenbank-Backup:''' Zwei-Schicht-Strategie für Calibre/CWA SQLite-Datenbanken | |||
---- | |||
== Teil 1: NVMe-Backup System (OS-Level) == | |||
=== Grundlegende Eigenschaften === | |||
* '''Zweck:''' Tägliche vollständige OS-Level Disaster Recovery Backups | |||
* '''Methode:''' rsync mit Hard Link Deduplication und <code>--one-file-system</code> | |||
* '''Backup-Größe:''' ~130GB pro Generation (apparent), ~37GB real durch Hard Links | |||
* '''Retention:''' 21 Tage (daily.0 bis daily.20) | |||
* '''Zeitplan:''' Täglich um 03:05 Uhr (±5min Randomisierung) | |||
=== Hardware-Konfiguration === | |||
* '''Quelle:''' NVMe System-Laufwerk (/) | |||
* '''Ziel:''' <code>/mnt/nvme_backup</code> - 1TB HDD (/dev/sdar1, ext4, Label: NVME_BACKUP) | |||
* '''Kapazität:''' 21 Backup-Generationen bei ~85% HDD-Auslastung (geschätzt 777GB) | |||
=== Hard Link Backup-Technologie === | |||
==== Funktionsweise der Deduplication ==== | |||
# '''Erste Generation (daily.0):''' Vollständiges Backup (~130GB apparent) | |||
# '''Folge-Generationen:''' Nur geänderte/neue Dateien verbrauchen Speicherplatz | |||
# '''Unveränderte Dateien:''' Hard Links zur vorherigen Generation (0 Byte zusätzlich) | |||
# '''Gemessene Effizienz:''' 98-99% aller Dateien sind Hard-Linked zwischen Generationen | |||
==== Realistische Speichernutzung ==== | |||
<code>daily.0: 130G apparent / 7.4GB real (neueste Generation) | |||
daily.1: 126G apparent / 85.5GB real (1 Tag alt) | |||
daily.2: 126G apparent / 4.1GB real (2 Tage alt)</code> | |||
'''Durchschnitt:''' ~37GB real pro Generation | |||
'''21 Generationen:''' ~777GB total (statt 2.7TB bei Vollbackups) | |||
==== Pseudo-Inkrementelles System ==== | |||
* Jede Generation erscheint als vollständiges Filesystem (130GB) | |||
* Tatsächlicher Speicherverbrauch nur für Änderungen | |||
* Wiederherstellung jeder Generation als komplettes System möglich | |||
* Keine Abhängigkeiten zwischen Generationen (jede ist vollständig) | |||
=== KRITISCH: Verzeichnis-Timestamps verstehen === | |||
'''WICHTIG:''' Die Timestamps der <code>daily.*</code> Verzeichnisse sind NICHT die Backup-Zeiten! | |||
'''Warum alle Verzeichnisse das gleiche Datum zeigen:''' | |||
* <code>mv</code> innerhalb desselben Filesystems ändert KEINE Directory-mtimes | |||
* Das Skript macht: <code>mv daily.0 daily.1</code>, <code>mv daily.1 daily.2</code>, etc. | |||
* Die Directory-Timestamps bleiben beim ersten Erstellen eingefroren | |||
'''Wo sind die ECHTEN Backup-Zeiten?''' | |||
# '''Log-Dateien:''' <code>/mnt/nvme_backup/_logs/run-YYYY-MM-DD_HH-MM-SS.log</code> | |||
# '''Datei-mtimes:''' Dateien INNERHALB der Backups haben korrekte mtimes | |||
# '''SystemD Journal:''' <code>journalctl -u nvme-backup.service</code> | |||
'''Backup-Alter prüfen:''' | |||
bash | |||
<code>ls -lth /mnt/nvme_backup/_logs/ | head</code> | |||
=== Software-Komponenten === | |||
==== SystemD Services ==== | |||
* '''Service:''' <code>nvme-backup.service</code> - OneShot-Service für Backup-Ausführung | |||
* '''Timer:''' <code>nvme-backup.timer</code> - Tägliche Ausführung um 03:05 Uhr (±5min) | |||
* '''Mail-Services:''' | |||
** <code>nvme-backup-mail@success.service</code> - Erfolgs-Benachrichtigung | |||
** <code>nvme-backup-mail@failure.service</code> - Fehler-Alarm | |||
==== Scripts und Pfade ==== | |||
* '''Backup-Script:''' <code>/usr/local/sbin/nvme-backup</code> (KEEP=21) | |||
* '''Mail-Script:''' <code>/usr/local/sbin/nvme-backup-mailer</code> | |||
* '''Log-Verzeichnis:''' <code>/mnt/nvme_backup/_logs/</code> | |||
* '''Backup-Verzeichnisse:''' <code>/mnt/nvme_backup/daily.0</code> bis <code>daily.20</code> | |||
=== Backup-Ablauf im Detail === | |||
==== Phase 1: Rotation (1-15 Minuten) ==== | |||
Das Skript rotiert die Verzeichnisse rückwärts: | |||
# Lösche <code>daily.21</code> (falls vorhanden) - <code>rm -rf</code> dauert lange! | |||
# Verschiebe <code>daily.20</code> → <code>daily.21</code> | |||
# Verschiebe <code>daily.19</code> → <code>daily.20</code> | |||
# ... bis <code>daily.0</code> → <code>daily.1</code> | |||
# Erstelle leeres <code>daily.0</code> | |||
'''WICHTIG:''' Das Löschen von <code>daily.21</code> kann 5-15 Minuten dauern (~49GB Hard-Links). Der Prozess "rm" erscheint in <code>top</code> mit hoher CPU-Last - das ist NORMAL! | |||
==== Phase 2: rsync (15-60 Minuten) ==== | |||
rsync kopiert von <code>/</code> nach <code>daily.0</code> mit: | |||
* <code>--link-dest=daily.1</code> (Hard Links für unveränderte Dateien) | |||
* <code>--delete</code> (entfernt gelöschte Dateien aus daily.0) | |||
* <code>--one-file-system</code> (ignoriert <code>/data</code>, <code>/data2</code>) | |||
* Fortschritt: Im Log <code>/mnt/nvme_backup/_logs/run-*.log</code> | |||
==== Phase 3: Fertigstellung ==== | |||
Script loggt "Backup OK" und beendet sich mit Exit 0. | |||
=== rsync-Parameter === | |||
'''Vollständiger Befehl:''' | |||
bash | |||
<code>rsync -aAXH --delete --numeric-ids --info=progress2 --one-file-system \ | |||
--link-dest=daily.1 / /mnt/nvme_backup/daily.0</code> | |||
'''Kritische Parameter:''' | |||
* <code>-a</code>: Archive-Mode (rlptgoD) - Permissions, Timestamps, etc. | |||
* <code>-A</code>: ACLs preservieren | |||
* <code>-X</code>: Extended Attributes preservieren | |||
* <code>-H</code>: Hard Links im Quell-System preservieren | |||
* <code>--delete</code>: Gelöschte Dateien auch aus Backup entfernen | |||
* <code>--numeric-ids</code>: UIDs/GIDs als Zahlen (nicht Namen) | |||
* <code>--one-file-system</code>: '''KRITISCH!''' Verhindert Backup der RAID-Mounts | |||
* <code>--link-dest</code>: Hard Links zu daily.1 für unveränderte Dateien | |||
=== Exclude-Liste === | |||
Das Skript schließt folgende Pfade aus: | |||
* <code>/proc/</code> - Kernel-Prozess-Dateisystem | |||
* <code>/sys/</code> - Kernel-System-Dateisystem | |||
* <code>/dev/</code> - Device-Dateien | |||
* <code>/run/</code> - Runtime-Daten | |||
* <code>/tmp/</code> - Temporäre Dateien | |||
* <code>/data/</code> - RAID-Mount md125 (XFS, 52TB) | |||
* <code>/data2/</code> - RAID-Mount md126 (EXT4, 61TB) | |||
* <code>/lost+found</code> - Dateisystem-Recovery | |||
* <code>/mnt/nvme_backup/*</code> - Backup-Ziel selbst | |||
=== Backup-Inhalt === | |||
'''Vollständig gesichert:''' | |||
* <code>/usr</code> (21GB) - System-Binaries | |||
* <code>/etc</code> (399MB) - Konfigurationen | |||
* <code>/boot</code> (417MB) - Kernel, Bootloader | |||
* <code>/var</code> (42GB) - Docker-Container, Emby-Metadaten, Systemlogs | |||
* <code>/home</code> (10.5GB) - User-Daten | |||
* <code>/srv</code> (9.5GB) - Service-Daten (Docker-Compose-Projekte) | |||
* <code>/opt</code> (1.5GB) - Zusatz-Software | |||
* <code>/root</code> (20GB) - Admin-Scripts und Configs | |||
=== KRITISCH: rsync Exitcode 24 === | |||
'''Problem:''' rsync gibt Exitcode 24 zurück, wenn Dateien während des Backups verschwinden. | |||
'''Ursachen (normal bei Live-Systemen):''' | |||
* Docker-Container schreiben/löschen Log-Dateien | |||
* Browser-Caches werden geleert | |||
* Temporäre Dateien verschwinden | |||
* Log-Rotation läuft parallel | |||
'''Lösung (seit 2025-10-11 implementiert):''' Exit-Codes 0, 23, 24 werden als Erfolg gewertet. Andere Exit-Codes lösen Fehler-Mail aus. | |||
'''Tolerierte Exit-Codes:''' | |||
* <code>0</code>: Perfekter Durchlauf | |||
* <code>23</code>: Partial transfer (z.B. Permission-Probleme bei einzelnen Dateien) | |||
* <code>24</code>: Some files vanished (normale Live-System-Situation) | |||
=== Mail-Benachrichtigungen === | |||
==== SMTP-Konfiguration ==== | |||
* '''Provider:''' GMX (mail.gmx.net:587, TLS) | |||
* '''Absender:''' dergagi@gmx.de | |||
* '''Empfänger:''' daniel.gareis@gmail.com | |||
* '''Auth:''' <code>/etc/msmtprc</code> (chmod 600) | |||
==== Mail-Inhalt bei Erfolg ==== | |||
* Backup-Statistiken (apparent/real size, übertragene Datenmenge) | |||
* Speicherplatz-Metriken (belegt/verfügbar/Prozent) | |||
* Retention-Info (Anzahl Generationen, geschätzte Kapazität) | |||
* System-Status (nächster Backup-Termin, RAID-Status) | |||
* Performance-Daten (Log-Größe, Dauer) | |||
==== Mail-Inhalt bei Fehler ==== | |||
* Error-Details aus journalctl | |||
* Backup-Festplatten-Status | |||
* Log-Pfad für weitere Diagnose | |||
* RAID-Status | |||
---- | |||
== Teil 2: Datenbank-Backup System (SQLite) == | |||
=== Übersicht === | |||
'''Zweck:''' Zwei-Schicht-Backup-Strategie für Calibre/Calibre-Web Datenbanken | |||
'''Problem:''' <code>/data</code> wird via <code>--one-file-system</code> vom OS-Backup ausgeschlossen | |||
'''Lösung:''' Separate DB-Backups mit unterschiedlichen Retention-Zeiten | |||
=== Warum separates DB-Backup? === | |||
'''Hintergrund:''' | |||
* Calibre-Bibliothek liegt auf <code>/data/ebooks/</code> (257GB E-Books + 50MB metadata.db) | |||
* Calibre-Web Config liegt auf <code>/data/ebooks-config/</code> (87GB Caches + 5MB app.db) | |||
* <code>/data</code> ist ein separates RAID6-Array (52TB) und wird vom NVMe-Backup ausgeschlossen | |||
'''Backup-Strategie:''' | |||
* '''E-Books selbst:''' NICHT gebackupt (257GB, zu groß, regenerierbar aus Quellen) | |||
* '''Datenbanken:''' KRITISCH für Recovery, nur ~70MB | |||
* '''Best Practice:''' SQLite-DBs benötigen konsistente Backups via <code>sqlite3 .backup</code> | |||
=== Zwei-Schicht-Architektur === | |||
==== Layer 1: Daily Safety Backup (NVMe) ==== | |||
'''Zweck:''' Schnelles Recovery bei CWA-Problemen oder Fehlkonfiguration | |||
'''Eigenschaften:''' | |||
* '''Ziel:''' <code>/mnt/nvme_backup/_data_dbs/</code> | |||
* '''Retention:''' 7 Tage (tägliche Ordner: YYYY-MM-DD) | |||
* '''Zeitplan:''' Täglich um 03:30 Uhr (nach Haupt-Backup) | |||
* '''Größe:''' ~70MB pro Backup | |||
* '''Service:''' <code>daily-db-backup.service</code> + <code>daily-db-backup.timer</code> | |||
'''Gebackupte Dateien:''' | |||
* <code>calibre_metadata</code> - <code>/data/ebooks/metadata.db</code> (50MB) | |||
* <code>calibre_prefs</code> - <code>/data/ebooks/metadata_db_prefs_backup.json</code> (16KB) | |||
* <code>cwa_app</code> - <code>/data/ebooks-config/app.db</code> (5MB) | |||
* <code>cwa_main</code> - <code>/data/ebooks-config/cwa.db</code> (15MB) | |||
'''Backup-Methode:''' | |||
* SQLite-DBs: <code>sqlite3 $src ".backup $dest"</code> + Integrity-Check | |||
* JSON-Dateien: Simple <code>cp -p</code> | |||
==== Layer 2: Weekly Archive Backup (RAID→RAID) ==== | |||
'''Zweck:''' Langzeit-Absicherung gegen Hardware-Fehler, tiefere Historie | |||
'''Eigenschaften:''' | |||
* '''Ziel:''' <code>/data2/db-archive/</code> | |||
* '''Retention:''' 4 Wochen (Ordner: YYYY-Wxx) | |||
* '''Zeitplan:''' Sonntag 04:00 Uhr | |||
* '''Größe:''' ~103MB pro Archiv (inkl. Backups + Logs) | |||
* '''Service:''' <code>weekly-archive-backup.service</code> + <code>weekly-archive-backup.timer</code> | |||
'''Gebackupte Dateien (erweitert):''' | |||
* Alle aus Daily Backup PLUS: | |||
* <code>calibre_metadata_backup</code> - <code>/data/ebooks/metadata.db.backup-*</code> (Wildcard) | |||
* <code>cwa_app_backup</code> - <code>/data/ebooks-config/app.db.backup-*</code> (Wildcard) | |||
* <code>cwa_logs</code> - <code>/data/ebooks-config/calibre-web.log*</code> (Diagnose) | |||
'''Vorteile:''' | |||
* RAID-zu-RAID: Besserer Hardware-Schutz als NVMe→HDD | |||
* Wildcard-Gruppen: Automatisches Backup aller DB-Versionen | |||
* Wöchentlich: Weniger Overhead, längere Geschichte | |||
=== Software-Komponenten === | |||
==== SystemD Services (Daily Backup) ==== | |||
* '''Service:''' <code>daily-db-backup.service</code> | |||
* '''Timer:''' <code>daily-db-backup.timer</code> (03:30 Uhr täglich) | |||
* '''Script:''' <code>/usr/local/sbin/daily-db-backup</code> | |||
* '''Logs:''' <code>/mnt/nvme_backup/_data_dbs/_logs/</code> | |||
==== SystemD Services (Weekly Backup) ==== | |||
* '''Service:''' <code>weekly-archive-backup.service</code> | |||
* '''Timer:''' <code>weekly-archive-backup.timer</code> (Sonntag 04:00 Uhr) | |||
* '''Script:''' <code>/usr/local/sbin/weekly-archive-backup</code> | |||
* '''Logs:''' <code>/data2/db-archive/_logs/</code> | |||
=== Backup-Ablauf === | |||
==== Daily Backup (03:30 Uhr) ==== | |||
# '''Backup-Ordner erstellen:''' <code>/mnt/nvme_backup/_data_dbs/YYYY-MM-DD/</code> | |||
# '''Für jede Datenbank:''' | |||
#* SQLite: <code>sqlite3 .backup</code> + <code>PRAGMA integrity_check</code> | |||
#* JSON: <code>cp -p</code> mit Timestamp-Erhalt | |||
# '''Retention:''' Löscht Backups älter als 7 Tage | |||
# '''Log:''' Schreibt detailliertes Log nach <code>_logs/</code> | |||
==== Weekly Backup (Sonntag 04:00 Uhr) ==== | |||
# '''Archiv-Ordner erstellen:''' <code>/data2/db-archive/YYYY-Wxx/</code> | |||
# '''Haupt-DBs backupen''' (wie Daily) | |||
# '''Wildcard-Gruppen backupen:''' | |||
#* Sucht alle <code>*.db.backup-*</code> Dateien | |||
#* Kopiert in Unterordner | |||
# '''Logs archivieren:''' Alle <code>calibre-web.log*</code> für Diagnose | |||
# '''Retention:''' Löscht Archive älter als 4 Wochen | |||
# '''Speicherplatz-Check:''' Zeigt <code>/data2</code> Belegung | |||
=== Wichtige Unterschiede zu OS-Backup === | |||
=== Service-Kontrolle === | |||
==== Status prüfen ==== | |||
bash | |||
<code>''# Daily Backup'' | |||
systemctl status daily-db-backup.timer | |||
systemctl status daily-db-backup.service | |||
ls -lth /mnt/nvme_backup/_data_dbs/_logs/ | head | |||
''# Weekly Backup'' | |||
systemctl status weekly-archive-backup.timer | |||
systemctl status weekly-archive-backup.service | |||
ls -lth /data2/db-archive/_logs/ | head</code> | |||
==== Manueller Start ==== | |||
bash | |||
<code>''# Daily Backup manuell ausführen'' | |||
systemctl start daily-db-backup.service | |||
''# Weekly Backup manuell ausführen'' | |||
systemctl start weekly-archive-backup.service</code> | |||
==== Backup-Struktur anzeigen ==== | |||
bash | |||
<code>''# Daily Backups (letzte 7)'' | |||
ls -lh /mnt/nvme_backup/_data_dbs/ | |||
''# Weekly Archive (letzte 4)'' | |||
ls -lh /data2/db-archive/ | |||
''# Detaillierter Inhalt eines Backups'' | |||
tree /mnt/nvme_backup/_data_dbs/2025-10-11/</code> | |||
---- | |||
== Teil 3: Wartung und Troubleshooting == | |||
=== NVMe-Backup Troubleshooting === | |||
==== Problem 1: Service schlägt fehl mit Exit 24 ==== | |||
'''Symptom:''' Mail "NVMe Backup FEHLGESCHLAGEN", journalctl zeigt "rsync warning: some files vanished" | |||
'''Ursache:''' Normale Live-System-Situation | |||
'''Lösung:''' Seit 2025-10-11 toleriert das Skript Exitcode 24. Bei älteren Skript-Versionen: Neues Skript installieren. | |||
==== Problem 2: Backup-Disk voll ==== | |||
'''Symptom:''' rsync schlägt fehl mit "No space left on device" | |||
'''Ursache:''' Mehr als erwartete Änderungen, oder Retention zu hoch | |||
'''Lösung:''' | |||
bash | |||
<code>''# KEEP von 21 auf 18 oder 15 reduzieren'' | |||
sed -i 's/KEEP=21/KEEP=18/' /usr/local/sbin/nvme-backup | |||
''# Alte Docker-Images aufräumen'' | |||
docker system prune -a | |||
''# Journal bereinigen'' | |||
journalctl --vacuum-time=30d</code> | |||
==== Problem 3: Backup dauert sehr lange ==== | |||
'''Symptom:''' rm-Prozess läuft 15+ Minuten | |||
'''Ursache:''' daily.21 hat sehr viele Dateien (Hard-Links brauchen Zeit zum Löschen) | |||
'''Lösung:''' Normal, abwarten. Ext4 braucht Zeit für Millionen Inodes. | |||
==== Problem 4: Verzeichnis-Timestamps sind alt ==== | |||
'''Symptom:''' "daily.0 zeigt 7. Sep, aber heute ist 11. Okt" | |||
'''Ursache:''' Normal! <code>mv</code> ändert keine Directory-mtimes | |||
'''Lösung:''' Logs anschauen für echte Backup-Zeiten: | |||
bash | |||
<code>ls -lth /mnt/nvme_backup/_logs/</code> | |||
=== DB-Backup Troubleshooting === | |||
==== Problem 1: SQLite Integrity-Check schlägt fehl ==== | |||
'''Symptom:''' Log zeigt "⚠ Integritäts-Check fehlgeschlagen" | |||
'''Ursache:''' Korrupte Datenbank im Live-System | |||
'''Lösung:''' | |||
bash | |||
<code>''# Manuelle Integritätsprüfung'' | |||
sqlite3 /data/ebooks/metadata.db "PRAGMA integrity_check;" | |||
''# Bei Korruption: Von älterem Backup wiederherstellen'' | |||
cp /mnt/nvme_backup/_data_dbs/2025-10-10/calibre_metadata \ | |||
/data/ebooks/metadata.db.restored</code> | |||
==== Problem 2: Wildcard-Gruppe findet keine Dateien ==== | |||
'''Symptom:''' Log zeigt "⚠ Keine Dateien gefunden" | |||
'''Ursache:''' Keine Backup-Dateien vorhanden (z.B. nach CWA-Neuinstallation) | |||
'''Lösung:''' Normal, keine Aktion nötig. Das Skript überspringt diese Gruppe. | |||
==== Problem 3: Backup schlägt mit Exit 1 fehl ==== | |||
'''Symptom:''' Service-Status zeigt "failed" | |||
'''Ursache:''' Quell-Datenbank nicht gefunden (z.B. Docker-Container gestoppt) | |||
'''Lösung:''' Prüfen ob CWA läuft: | |||
bash | |||
<code>docker ps | grep calibre | |||
ls -lh /data/ebooks-config/app.db</code> | |||
=== Wiederherstellung (Recovery) === | |||
==== Daily Backup Recovery (schnell) ==== | |||
'''Szenario:''' CWA-Datenbank nach Update korrupt | |||
bash | |||
<code>''# 1. CWA stoppen'' | |||
docker stop calibre-web | |||
''# 2. Backup wiederherstellen (gestern)'' | |||
cp /mnt/nvme_backup/_data_dbs/2025-10-10/cwa_app \ | |||
/data/ebooks-config/app.db | |||
''# 3. Permissions korrigieren'' | |||
chown gagi:gagi /data/ebooks-config/app.db | |||
''# 4. CWA starten'' | |||
docker start calibre-web</code> | |||
==== Weekly Archive Recovery (tiefer) ==== | |||
'''Szenario:''' Calibre-Bibliothek korrupt, brauche Version von vor 3 Wochen | |||
bash | |||
<code>''# 1. Verfügbare Archive anzeigen'' | |||
ls -lh /data2/db-archive/ | |||
''# 2. Gewünschte Woche finden (z.B. 2025-W38)'' | |||
ls -lh /data2/db-archive/2025-W38/ | |||
''# 3. Backup wiederherstellen'' | |||
cp /data2/db-archive/2025-W38/calibre_metadata \ | |||
/data/ebooks/metadata.db | |||
''# 4. Permissions'' | |||
chown gagi:gagi /data/ebooks/metadata.db | |||
''# 5. Calibre restarten (falls Container läuft)'' | |||
docker restart calibre</code> | |||
==== Vollständige System-Wiederherstellung (NVMe) ==== | |||
'''Szenario:''' NVMe-SSD versagt komplett | |||
bash | |||
<code>''# 1. Neue NVMe-SSD einbauen'' | |||
''# 2. Debian 13 Minimal installieren'' | |||
''# 3. Backup-HDD mounten'' | |||
mount /dev/sdar1 /mnt/backup | |||
''# 4. System wiederherstellen'' | |||
rsync -aAXH --numeric-ids /mnt/backup/daily.0/ /mnt/newsystem/ | |||
''# 5. Bootloader neu installieren'' | |||
chroot /mnt/newsystem | |||
grub-install /dev/nvme0n1 | |||
update-grub | |||
exit | |||
''# 6. Reboot'' | |||
reboot</code> | |||
---- | |||
== Teil 4: Performance und Kapazität == | |||
=== NVMe-Backup Performance === | |||
* '''Erstes Backup:''' ~130GB in 1,5 Stunden (Vollübertragung) | |||
* '''Folge-Backups:''' ~5-40GB in 15-60 Minuten (nur Änderungen) | |||
* '''CPU-Verbrauch:''' ~4 Minuten CPU-Zeit pro Backup | |||
* '''Memory Peak:''' ~5.7GB während Backup | |||
* '''Hard Link Effizienz:''' 98-99% Dateien verlinkt zwischen Generationen | |||
* '''Durchschnittlicher Speicherverbrauch:''' 37GB real pro Generation | |||
'''Rotation (rm -rf daily.21):''' | |||
* '''Dauer:''' 5-15 Minuten | |||
* '''CPU:''' 20-30% eines Cores | |||
* '''Grund:''' Millionen Hard-Links müssen aufgelöst werden | |||
=== DB-Backup Performance === | |||
* '''Daily Backup:''' ~3 Sekunden (4 Dateien, 70MB) | |||
* '''Weekly Backup:''' ~5 Sekunden (7 Items, 103MB) | |||
* '''CPU-Verbrauch:''' Minimal (<1% Core) | |||
* '''Speicherverbrauch:''' ~500MB pro Woche | |||
=== Kapazitäts-Management === | |||
==== NVMe-Backup ==== | |||
* '''Aktuelle Nutzung (typisch):''' 330-400GB für 21 Generationen | |||
* '''Projektion 21 Tage:''' ~777GB (85% der 916GB HDD) | |||
* '''Sicherheitspuffer:''' ~140GB für Variabilität | |||
* '''Überwachung:''' Automatisch via Mail nach jedem Backup | |||
==== DB-Backups ==== | |||
* '''Daily (NVMe):''' 7 × 70MB = ~490MB | |||
* '''Weekly (RAID):''' 4 × 103MB = ~412MB | |||
* '''Total:''' <1GB für beide Backup-Layer | |||
'''Notfall-Maßnahmen bei Speicherknappheit (NVMe-Backup):''' | |||
Option 1: Retention reduzieren | |||
bash | |||
<code>sed -i 's/KEEP=21/KEEP=18/' /usr/local/sbin/nvme-backup</code> | |||
Option 2: System-Dateien aufräumen | |||
bash | |||
<code>docker system prune -a | |||
journalctl --vacuum-time=30d | |||
apt clean && apt autoclean</code> | |||
Option 3: Manuelle Backup-Löschung | |||
bash | |||
<code>rm -rf /mnt/nvme_backup/daily.20 | |||
rm -rf /mnt/nvme_backup/daily.19</code> | |||
---- | |||
== Teil 5: Integration in Gesamtsystem == | |||
=== Drei-Schicht-Backup-Architektur === | |||
'''Layer 1: RAID6-Arrays (Live-Redundanz)''' | |||
* <code>/data</code> (md125, XFS, 52TB) - E-Books, Medien | |||
* <code>/data2</code> (md126, EXT4, 61TB) - Backups, Archive | |||
* '''Zweck:''' Hardware-Redundanz gegen Festplattenausfall | |||
'''Layer 2: NVMe-Backup (System-Recovery)''' | |||
* Ziel: <code>/mnt/nvme_backup</code> (1TB HDD) | |||
* Retention: 21 Tage | |||
* '''Zweck:''' Vollständige OS-Wiederherstellung, 3-Wochen-Historie | |||
'''Layer 3: DB-Backups (Datenbank-Schutz)''' | |||
* Daily: <code>/mnt/nvme_backup/_data_dbs/</code> (7 Tage) | |||
* Weekly: <code>/data2/db-archive/</code> (4 Wochen) | |||
* '''Zweck:''' SQLite-konsistente Backups für Calibre/CWA | |||
=== Optimierte Ressourcen-Aufteilung === | |||
* '''RAID-Schutz:''' 113TB Nutzdaten mit Hardware-Redundanz | |||
* '''NVMe-Backup:''' 130GB System-Recovery mit 3-Wochen-Historie | |||
* '''DB-Backups:''' <1GB für 7+28 Tage Datenbank-Historie | |||
* '''Hard Link Effizienz:''' 777GB für 21 Vollbackups (statt 2.7TB) | |||
=== Zeitplan-Koordination === | |||
<code>03:05 Uhr: NVMe-Backup (OS-Level) startet | |||
03:30 Uhr: Daily DB-Backup startet (nach OS-Backup) | |||
04:00 Uhr: Weekly Archive-Backup (nur Sonntag)</code> | |||
'''Grund:''' DB-Backups laufen NACH dem Haupt-Backup, um Konflikte zu vermeiden. | |||
---- | |||
== Changelog == | |||
'''v3.0 (2025-10-11):''' | |||
* Zwei-Schicht-DB-Backup-System hinzugefügt | |||
* Daily Safety Backup (NVMe, 7 Tage) | |||
* Weekly Archive Backup (RAID→RAID, 4 Wochen) | |||
* SQLite <code>.backup</code> API für konsistente DB-Kopien | |||
* Separate SystemD Services/Timers für DB-Backups | |||
* Dokumentation komplett überarbeitet und erweitert | |||
'''v2.0 (2025-10-11):''' | |||
* Exit-Code-24-Toleranz hinzugefügt (Exit 0/23/24 = Erfolg) | |||
* Dokumentation zu Directory-Timestamps ergänzt | |||
* Troubleshooting-Sektion erweitert | |||
* Performance-Charakteristika gemessen und dokumentiert | |||
'''v1.0 (2025-09-07):''' | |||
* Initiale 21-Tage-Retention | |||
* Mail-Benachrichtigungen implementiert | |||
* Hard-Link-Backup produktiv | |||
----'''Ende der Dokumentation v3.0''' | |||
= STORE2 NVME Disaster Recovery Dokumentation = | |||
== Übersicht == | |||
Diese Dokumentation beschreibt die vollständige Wiederherstellung des STORE2-Servers nach einem totalen NVMe-SSD-Ausfall. Das Verfahren basiert auf täglichen rsync-Backups mit Hard-Link-Deduplication. | |||
'''Systemdaten:''' | |||
* Backup-System: rsync mit --link-dest (21 Generationen) | |||
* Backup-Größe: ~118GB pro Generation | |||
* Recovery-Zeit: 4-5 Stunden gesamt | |||
* Besonderheit: RAID-Arrays sind mit LUKS verschlüsselt! | |||
== Voraussetzungen == | |||
=== Hardware-Anforderungen === | |||
* Neue NVMe SSD (Minimum: 256GB, Empfohlen: 512GB, Optimal: 1TB) | |||
* Debian 13 Live-USB oder Installations-Medium | |||
* Physischer Zugriff auf STORE2 | |||
* Monitor und Tastatur | |||
* Netzwerkkabel für spätere Updates | |||
=== Kritische Systeminformationen (STORE2 Stand: September 2025) === | |||
'''System-Partitionierung:''' | |||
* /dev/nvme0n1p1: 222,6GB ext4 (Root-Partition) | |||
* /dev/nvme0n1p5: 15,9GB swap | |||
* Root-UUID: 0bcdb676-123c-4658-925e-9cba9ecf45df | |||
'''Backup-HDD:''' | |||
* Device: /dev/sdar1 | |||
* Filesystem: ext4 | |||
* Label: NVME_BACKUP | |||
* UUID: 1c2b9b3c-f436-404a-9777-aa288477a7a8 | |||
* Mount: /mnt/nvme_backup | |||
'''RAID-Arrays (VERSCHLÜSSELT mit LUKS!):''' | |||
* md125: RAID6, 20 Disks, 52TB, XFS, verschlüsselt | |||
** LUKS UUID: a54ac812-bb0e-4228-b3f7-2961fbb74ce7 | |||
** Decrypted: /dev/mapper/cr_md125 | |||
** Filesystem UUID: 9787dc50-bdd5-4054-901c-bf4657db7ab4 | |||
** Mount: /data | |||
* md126: RAID6, 23 Disks, 61TB, EXT4, verschlüsselt | |||
** LUKS UUID: 82d138cd-958d-42bc-b0f2-08eaa06f447d | |||
** Decrypted: /dev/mapper/cr_md126 | |||
** Filesystem UUID: 72ee2927-2855-4ebd-a7d0-3d8f4a3450c1 | |||
** Mount: /data2 | |||
'''Netzwerk:''' | |||
* Interface: enp0s31f6 (NICHT eth0!) | |||
* MAC: 30:9c:23:68:bf:e8 | |||
* Hostname: STORE2 | |||
* Domain: dergagi.changeip.org | |||
== Phase 1: Vorbereitung (30 Minuten) == | |||
=== 1.1 Hardware-Vorbereitung === | |||
# Server herunterfahren: shutdown -h now | |||
# Stromversorgung trennen | |||
# Defekte NVMe entfernen | |||
# Neue NVMe einbauen | |||
# '''WICHTIG:''' Backup-HDD (/dev/sdar1) und RAID-Disks NICHT entfernen! | |||
=== 1.2 Informationen dokumentieren (falls System noch läuft) === | |||
Folgende Befehle ausführen und Ausgaben sichern: | |||
lsblk -f > /tmp/lsblk-output.txt blkid > /tmp/blkid-output.txt ip link show > /tmp/network-interfaces.txt cat /proc/mdstat > /tmp/raid-status.txt cat /etc/fstab > /tmp/fstab-backup.txt cat /etc/crypttab > /tmp/crypttab-backup.txt | |||
Diese Dateien auf USB-Stick oder per Mail sichern! | |||
== Phase 2: Basis-Installation (45 Minuten) == | |||
=== 2.1 Debian 13 installieren === | |||
# Von Debian 13 USB/DVD booten | |||
# Installationstyp: Minimal (ohne Desktop-Umgebung) | |||
# Partitionierung EXAKT wie Original: | |||
#* /dev/nvme0n1p1: 223GB ext4 für / | |||
#* /dev/nvme0n1p5: 16GB swap | |||
# Hostname: STORE2 (wichtig!) | |||
# Root-Passwort: Temporär (wird überschrieben) | |||
# Netzwerk: NICHT konfigurieren | |||
# Software: Nur "Standard-Systemwerkzeuge" | |||
=== 2.2 Nach Installation === | |||
* System einmal booten lassen | |||
* Als root anmelden | |||
* Herunterfahren: shutdown -h now | |||
== Phase 3: Recovery via Live-System (2-3 Stunden) == | |||
=== 3.1 Live-System vorbereiten === | |||
# Von Debian Live-USB booten | |||
# Terminal öffnen | |||
# Root werden: sudo -i | |||
=== 3.2 Partitionen identifizieren === | |||
lsblk -f | |||
==== Backup-HDD finden (Label: NVME_BACKUP) ==== | |||
blkid | grep NVME_BACKUP | |||
==== Sollte zeigen: /dev/sdar1 ==== | |||
==== Neue NVMe-Root finden ==== | |||
blkid | grep nvme0n1p1 | |||
==== NEUE UUID notieren! ==== | |||
=== 3.3 Partitionen mounten === | |||
mkdir -p /mnt/new-system mkdir -p /mnt/backup | |||
==== Neue NVMe mounten ==== | |||
mount /dev/nvme0n1p1 /mnt/new-system | |||
==== Backup-HDD mounten (normalerweise sdar1) ==== | |||
mount /dev/sdar1 /mnt/backup | |||
==== Prüfen ==== | |||
df -h | grep mnt | |||
=== 3.4 System wiederherstellen === | |||
'''WICHTIG: Dieser Schritt dauert 2-3 Stunden!''' | |||
rsync -aAXHv --info=progress2 | |||
--exclude='/proc/''<nowiki/>''' | |||
''--exclude='/sys/''<nowiki/>' | |||
--exclude='/dev/''<nowiki/>''' | |||
''--exclude='/run/''<nowiki/>' | |||
--exclude='/tmp/''<nowiki/>''' | |||
''--exclude='/mnt/''<nowiki/>' | |||
/mnt/backup/daily.0/ /mnt/new-system/ | |||
Erwartete Werte: | |||
* Dateien: ~1.7 Millionen | |||
* Daten: ~118GB | |||
* Dauer: 2-3 Stunden | |||
== Phase 4: System-Anpassung (1 Stunde) == | |||
=== 4.1 Chroot vorbereiten === | |||
'''KRITISCH: Exakte Reihenfolge beachten!''' | |||
mkdir -p /mnt/new-system/{dev,proc,sys,run} | |||
mount --bind /dev /mnt/new-system/dev mount --bind /proc /mnt/new-system/proc mount --bind /sys /mnt/new-system/sys mount --bind /run /mnt/new-system/run mount --bind /dev/pts /mnt/new-system/dev/pts | |||
chroot /mnt/new-system /bin/bash | |||
==== Test ob chroot funktioniert ==== | |||
ls /root cat /etc/hostname # Sollte "STORE2" zeigen | |||
=== 4.2 Hardware-Anpassungen === | |||
'''UUID in /etc/fstab anpassen:''' | |||
==== Neue UUID ermitteln ==== | |||
blkid | grep nvme0n1p1 | |||
==== Beispiel: UUID="neue-uuid-hier" ==== | |||
==== Backup ==== | |||
cp /etc/fstab /etc/fstab.backup | |||
==== fstab editieren ==== | |||
nano /etc/fstab | |||
==== ÄNDERN: ==== | |||
==== ALT: UUID=0bcdb676-123c-4658-925e-9cba9ecf45df / ext4 ... ==== | |||
==== NEU: UUID=NEUE-UUID-HIER / ext4 ... ==== | |||
==== Syntax prüfen ==== | |||
mount -a | |||
==== Sollte keine Fehler zeigen (Warnungen OK) ==== | |||
'''GRUB neu installieren:''' | |||
grub-install /dev/nvme0n1 | |||
==== Sollte zeigen: ==== | |||
==== Installing for x86_64-efi platform. ==== | |||
==== Installation finished. No error reported. ==== | |||
update-grub | |||
==== Sollte Kernel finden und grub.cfg generieren ==== | |||
'''Initramfs neu bauen:''' | |||
update-initramfs -u -k all | |||
=== 4.3 Netzwerk anpassen === | |||
==== Interface-Namen prüfen ==== | |||
ip link show | |||
==== /etc/network/interfaces editieren ==== | |||
nano /etc/network/interfaces | |||
==== Falls Interface-Name anders (meist enp0s31f6 statt eth0): ==== | |||
==== allow-hotplug enp0s31f6 ==== | |||
==== iface enp0s31f6 inet dhcp ==== | |||
=== 4.4 Chroot verlassen und unmounten === | |||
exit | |||
==== Unmount in UMGEKEHRTER Reihenfolge! ==== | |||
umount /mnt/new-system/dev/pts umount /mnt/new-system/run umount /mnt/new-system/sys umount /mnt/new-system/proc umount /mnt/new-system/dev umount /mnt/new-system umount /mnt/backup | |||
reboot | |||
== Phase 5: Post-Recovery (30 Minuten) == | |||
=== 5.1 Erster Boot === | |||
Nach dem Boot als root einloggen: | |||
==== Netzwerk prüfen ==== | |||
ip a ping -c 3 8.8.8.8 | |||
==== Falls kein Netzwerk: ==== | |||
systemctl restart networking | |||
==== SSH aktivieren ==== | |||
systemctl start ssh systemctl enable ssh | |||
=== 5.2 RAID-Arrays wiederherstellen === | |||
'''WICHTIG: Arrays sind LUKS-verschlüsselt!''' | |||
'''Arrays assemblieren:''' | |||
mdadm --assemble --scan | |||
'''Status prüfen:''' | |||
cat /proc/mdstat | |||
==== Sollte md125 und md126 zeigen ==== | |||
'''LUKS entsperren (Passwort erforderlich!):''' | |||
cryptsetup luksOpen /dev/md125 cr_md125 cryptsetup luksOpen /dev/md126 cr_md126 | |||
'''Mounten:''' | |||
mount /dev/mapper/cr_md125 /data mount /dev/mapper/cr_md126 /data2 | |||
'''Prüfen:''' | |||
df -h | grep data | |||
'''Für automatisches Entsperren beim Boot:''' | |||
==== /etc/crypttab prüfen/anpassen! ==== | |||
=== 5.3 Docker-Services starten === | |||
systemctl status docker | |||
==== Falls nicht läuft: ==== | |||
systemctl start docker | |||
==== Container-Status ==== | |||
docker ps -a | |||
==== Alle Container starten ==== | |||
docker start $(docker ps -aq) | |||
==== Warten (2-3 Minuten) ==== | |||
docker ps | |||
=== 5.4 Kritische Services prüfen === | |||
==== Apache ==== | |||
systemctl status apache2 curl -k <nowiki>https://localhost/site</nowiki> | |||
==== Backup-Timer ==== | |||
systemctl status nvme-backup.timer systemctl list-timers | grep backup | |||
==== Emby ==== | |||
systemctl status emby-server | |||
==== Alle fehlgeschlagenen Services anzeigen ==== | |||
systemctl list-units --failed | |||
== Phase 6: Vollständige Verifikation == | |||
=== 6.1 Service-Checkliste === | |||
'''Zu prüfende Services:''' | |||
=== 6.2 Docker-Container prüfen === | |||
==== Alle Container sollten "Up" sein ==== | |||
docker ps --format "table <nowiki>{{.Names}}</nowiki>\t<nowiki>{{.Status}}</nowiki>" | |||
==== Logs bei Problemen prüfen ==== | |||
docker logs <container-name> | |||
==== 6.3 RAID-Integrität ==== | |||
==== RAID-Status detailliert ==== | |||
mdadm --detail /dev/md125 mdadm --detail /dev/md126 | |||
==== Smart-Status der RAID-Disks ==== | |||
smartctl -a /dev/sda | grep -E "SMART overall|Reallocated" | |||
==== Troubleshooting ==== | |||
=== Problem: GRUB Error "no such device" === | |||
# Von Live-USB booten | |||
# Chroot-Prozedur wiederholen | |||
# UUID in /etc/fstab nochmals prüfen | |||
# update-grub erneut ausführen | |||
=== Problem: Netzwerk funktioniert nicht === | |||
ip link show | |||
==== Interface-Name notieren (z.B. enp0s31f6) ==== | |||
nano /etc/network/interfaces | |||
==== Interface-Namen anpassen ==== | |||
systemctl restart networking | |||
=== Problem: RAID-Arrays werden nicht entschlüsselt === | |||
==== Prüfen ob Arrays da sind ==== | |||
cat /proc/mdstat | |||
==== Manuell entsperren ==== | |||
cryptsetup luksOpen /dev/md125 cr_md125 cryptsetup luksOpen /dev/md126 cr_md126 | |||
==== /etc/crypttab prüfen ==== | |||
cat /etc/crypttab | |||
==== Sollte beide Arrays enthalten ==== | |||
=== Problem: Docker-Container starten nicht === | |||
systemctl restart docker docker start <container-name> docker logs <container-name> | |||
== Zeitplan == | |||
== Kritische Hinweise == | |||
'''RAID-Verschlüsselung:''' Die RAID-Arrays md125 und md126 sind mit LUKS verschlüsselt! Das Entschlüsselungs-Passwort wird benötigt. Ohne dieses Passwort sind die 113TB Daten nicht zugänglich. | |||
'''Interface-Namen:''' Das Netzwerk-Interface heißt enp0s31f6, NICHT eth0. Dies muss in /etc/network/interfaces angepasst werden. | |||
'''Docker-Volumes:''' Alle im Backup enthalten unter /var/lib/docker/volumes/ | |||
'''Backup-HDD:''' Device /dev/sdar1 mit Label NVME_BACKUP - NIEMALS formatieren! | |||
'''IP-Adressen:''' Bei MAC-Änderung könnte DHCP neue IP vergeben. | |||
== Notfall-Kontakte == | |||
* Zugriff via Live-System immer möglich | |||
* Backup-HDD (/dev/sdar1) ist die Lebensversicherung | |||
* RAID-LUKS-Passwort sicher aufbewahrt? | |||
* Logs in /var/log/ und /root/chatgpt-logs/ | |||
== Nach erfolgreicher Recovery == | |||
'''Backup-System prüfen:''' | |||
==== Backup-Timer prüfen ==== | |||
systemctl status nvme-backup.timer systemctl list-timers | grep nvme | |||
==== Test-Backup ==== | |||
systemctl start nvme-backup.service | |||
==== Log beobachten ==== | |||
tail -f /mnt/nvme_backup/_logs/run-*.log | |||
= HDD als NTFS unter Linux richtig formatieren = | |||
Szenario: Raid-Platte geht noch, liefert aber sporadische Fehler in dmesg z.B. -> wird im Raid ersetzt -> ist dann "über" -> kann als Serien-Sammelplatte noch verwendet werden | |||
Damit die Platte auch unter Windows richtig erkannt wird ist folgendes zu beachten: | |||
Partitionstyp muss auf 0x07 (HPFS/NTFS/exFAT) stehen! | |||
Partitionieren mit gdisk | |||
sudo gdisk /dev/sdX | |||
* erst alte Linux Raid Partiton löschen: d -> 1 -> w | |||
* <code>n</code> → Neue Partition anlegen (Eingaben bestätigen oder (falls gewünscht) Start- und Endsektor anpassen) | |||
* <code>0700</code> als Typ für NTFS setzen (wird ggf. vorgeschlagen, sonst nachfragen) | |||
* <code>w</code> → Schreiben und gdisk verlassen | |||
Formatieren mit mkfs.ntfs | |||
sudo mkfs.ntfs -f /dev/sdX1 | |||
Mounten mit | |||
sudo mkdir -p /mnt/ntfs | |||
sudo mount -t ntfs-3g /dev/sdX1 /mnt/ntfs | |||
= Booten überhaupt !!! = | |||
Bios 12 ist OK. Kerne laufen beide auf 2.5Ghz. | |||
Beide Karten sind OK und müssen auch beim Booten drin sein | |||
Wenn die Laufwerke vom 4-Ch Sata-Controller ab sind, wir auch gebootet. | |||
Dann können sie Hot-Geplugged werden -> geht :-) | |||
Jetzt testen dass auch alle 27 (!) Laufwerke da sind. | |||
/root/bin/diskserial_sort.sh | |||
Dann weiter wie im Raidabschnitt beschrieben | |||
mdadm --assemble --scan | |||
= Raid-Karten Kernel-Treiber nach Kernelupdate = | |||
cd /Nach_Kernelupdate/rr2340-linux-src-v1.7/product/rr2340/linux/ | |||
make clean | |||
make | |||
make install | |||
Manuelles starten (nach Reboot automatisch) | |||
modprobe rr2340 | |||
= Grub und Root-Festplatte = | |||
in /boot/grub/menu.lst z.B. | |||
kernel /boot/vmlinuz-2.6.31.14-0.6-desktop root=UUID=d06e4d6a-44d7-4f09-9ea3-a4cb8f120770 ... | |||
= UUID einer Festplatte herausfinden = | |||
blkid /dev/sdq8 | |||
= Screen-Umgebung = | |||
http://linuxwiki.de/screen | |||
Liste aller Screens | |||
screen -ls | |||
Starten | |||
screen -S NAME | |||
Detach | |||
Strg-a d = detach | |||
Reatach | |||
screen -r NAME | |||
ODER | |||
Wieder reingehen | |||
screen -x NAME | |||
Screens beenden | |||
im Screen Strg-a k (wie kill) | |||
= Arch Linux AUR Pakete = | |||
- tarball herunterladen | |||
- nach /builds entpacken (tar -xzf xxxx.tar.gz) | |||
- dort makepkg | |||
- pacman -U xxxx.pkg.tar.xz | |||
= RAR unter Linux = | |||
RAR-Archiv testen | |||
rar t xxxxx.rar | |||
= Wake-On-Lan = | = Wake-On-Lan = | ||
Netzwerkkarte in System->Gerätemanager erlauben und Magic Paket einstellen | Netzwerkkarte in System->Gerätemanager erlauben und Magic Paket einstellen | ||
im Bios PCI aufwecken erlauben | im Bios PCI aufwecken erlauben | ||
Mac-Adresse und Netzwerk-IP wissen | Mac-Adresse und Netzwerk-IP wissen | ||
== Uni == | |||
Linux-Konsolen-Befehl zum Aufwecken auf | Linux-Konsolen-Befehl zum Aufwecken auf | ||
Uni-Rechner Big-Blue2: | Uni-Rechner Big-Blue2 aus "Hibernate": | ||
wol -i 132.187.33.255 90:e6:ba:43:c2:dc | wol -i 132.187.33.255 90:e6:ba:43:c2:dc | ||
Brücknerstrasse | Busfahrer an Uni: | ||
Bachus | wol -i 132.187.33.255 b8:ac:6f:67:e6:43 | ||
wol -i | |||
Myth | == Brücknerstrasse == | ||
wol -i | Aufwecken aus "Standby" | ||
(Bachus) | |||
wol -i 255.255.255.255 00:1e:8c:46:10:8c | |||
(Myth intern) | |||
wol -i 255.255.255.255 00:14:85:e8:10:4c | |||
Myth PCIe | |||
'''wol -i 255.255.255.255 00:e0:45:49:00:09''' | |||
Tool um Windows um Remote-Verbindung schlafen zu legen PowerOff z.B. bei | |||
http://www.chip.de/downloads/Poweroff_21571048.html | |||
Linuxbefehl für OpenSuse um per Konsole zu suspenden: | |||
pm-suspend | |||
-> Vorsicht: Festplatten verhalten sich komisch | |||
"HDIO_DRIVE_CMD(identify) failed: Invalid exchange" | |||
bei | |||
/root/bin/diskserial_sort.sh | |||
Aufwecken über Fritzbox direkt problemlos möglich. | |||
= Remote-Desktop = | |||
Big-Blue: | |||
SSH auf wolf.physik.uni-wuerzburg.de mit Tunnel: | |||
33889 auf Ziel 132.187.33.133:3389 | |||
Dann localhost:33889 | |||
Myth: | |||
dergagi.dyndns.org normal (ohne Angabe gilt Port 3389) | |||
Bachus: | |||
dergagi.dyndns.org:33890 | |||
= Ordnergröße in Konsole anzeigen = | = Ordnergröße in Konsole anzeigen = | ||
| Zeile 19: | Zeile 2.139: | ||
df -h | df -h | ||
= DU-Meter für SuSE = | = DU-Meter für SuSE/Linux = | ||
KTrafficAnalyzer, z.B. über 1-Klick Installation bei | KTrafficAnalyzer, z.B. über 1-Klick Installation bei | ||
http://software.opensuse.org/search | http://software.opensuse.org/search | ||
NTM | |||
http://netramon.sourceforge.net/eng/index.html | |||
= Bandwidth-Monitor für Console, z.B. auch Ubuntu = | |||
bwm-ng | |||
bmon | |||
= Netzwerk-Geschwindkeit testen = | |||
Tool: iperf | |||
gibts für Linux, Windows, Mac | |||
Server (empfängt Testdaten) | |||
iperf -s | |||
Client (sendet Daten) | |||
iperf -c 192.168.1.60 (Myth) | |||
ipfer -c 192.168.1.66 (Store) | |||
= Manuel RPM Pakete installieren = | = Manuel RPM Pakete installieren = | ||
| Zeile 35: | Zeile 2.174: | ||
mount -t ntfs-3g /dev/sdj5 /usb -o force | mount -t ntfs-3g /dev/sdj5 /usb -o force | ||
NTFS Linux | |||
mount -t ntfs-3g /dev/sds1 /mo1 | |||
= Opensuse: IP über DHCP erneuern = | = Opensuse: IP über DHCP erneuern = | ||
| Zeile 53: | Zeile 2.195: | ||
= Devices neu einlesen im laufenden Betrieb ohne Reboot = | = Devices neu einlesen im laufenden Betrieb ohne Reboot = | ||
blockdev --rereadpt /dev/sdx | blockdev --rereadpt /dev/sdx | ||
= Laufwerke am RocketRaid neu einlesen im laufenden Betrieb ohne Reboot = | |||
Kernelmodul da? | |||
lsmod rr2340 | |||
Kernelmodul entfernen/löschen | |||
rmmod rr2340 | |||
Kernelmodul wieder laden/starten | |||
modprobe rr2340 | |||
= KDE Remote Desktop = | = KDE Remote Desktop = | ||
| Zeile 64: | Zeile 2.214: | ||
Kontrolle unter: | Kontrolle unter: | ||
vi home/root/kde4/share/config/krfbrc | vi home/root/kde4/share/config/krfbrc | ||
= JDownloader = | |||
Installieren über Script von Homepage | |||
1. wget must be installed on system! | |||
2. Download jd.sh | |||
http://212.117.163.148/jd.sh | |||
3. chmod +x jd.sh | |||
4. start jd.sh -> ./jd.sh | |||
Note: Open jd.sh to read Manual or change Settings! | |||
Starten nach Installation: | |||
java -jar /home/gagi/.jd/JDownloader.jar | |||
= One-Click Install auf Konsole = | = One-Click Install auf Konsole = | ||
OCICLI <YMP URL> | OCICLI <YMP URL> | ||
= Cronjobs = | |||
Liste | |||
crontab -l | |||
Einträge ändern | |||
crontab -e | |||
dort dann im vi editieren | |||
= Data Scrubbing, automatische Suche einmal im Monat nach BadBlocks = | = Data Scrubbing, automatische Suche einmal im Monat nach BadBlocks = | ||
| Zeile 94: | Zeile 2.263: | ||
echo idle >> /sys/block/md127/md/sync_action | echo idle >> /sys/block/md127/md/sync_action | ||
echo idle >> /sys/block/md125/md/sync_action | echo idle >> /sys/block/md125/md/sync_action | ||
= TigerVNC = | |||
Start Server | |||
vncserver :1 | |||
vncserver :2 | |||
Kill Server | |||
vncserver -kill :1 | |||
Port 5901 | |||
dergagi.selfhost.bz:5901 | |||
dergagi.selfhost.bz:5902 | |||
Auflösung ändern: | |||
im VNC-Fenster (also schon remote) | |||
xrandr -s 1920x1200 | |||
XTerm Benutzer wechseln: | |||
su gagi | |||
Autostart | |||
in /etc/rc.local | |||
su gagi -c "vncserver -geometry 1920x1080 -alwaysshared -localhost -dpi 96 :1" | |||
= RSYNC volles Systembackup = | |||
rsync -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/data","/data2","/suse","/rsync-backup"} / /rsync-backup/ | |||
Aktuelle Version vom 11. Oktober 2025, 18:28 Uhr
STORE2 NETZWERK-ARCHITEKTUR - KURZREFERENZ
KRITISCHE ARCHITEKTUR-GRUNDLAGEN
Drei parallele Zugriffswege:
- Apache Reverse Proxy (Port 443/80) → Domain
dergagi.changeip.org - Traefik Reverse Proxy (Port 8444/81) → Nextcloud
nc.dergagi9.duckdns.org:8444 - Direkte HTTP-Ports → Dienste ohne Proxy
APACHE VIRTUALHOST STRUKTUR (PORT 443)
Zwei VirtualHosts auf Port 443:
000-catchall-443.conf(ServerName: catchall.local, default)000-website-dergagi-443.conf(ServerName: dergagi.changeip.org)
KRITISCH: Beide VirtualHosts haben identische ProxyPass-Regeln, weil catchall als Default viele Requests abfängt.
Aktive ProxyPass-Routen:
/w/ → http://127.0.0.1:8088 (MediaWiki, Docker)
/yt4k/ → http://127.0.0.1:8443 (YT4K, SystemD)
/ombi/ → http://127.0.0.1:3579/ombi/ (Ombi, Docker)
/cwa → http://127.0.0.1:8084 (Calibre-Web, Docker)
/api → http://127.0.0.1:8443/api
Port 444: Home Assistant Proxy → http://127.0.0.1:8123
KRITISCHE ERKENNTNISSE (LESSONS LEARNED)
1. conf-enabled Dateien sind gefährlich
Problem: /etc/apache2/conf-enabled/yt4k-*.conf überschrieb VirtualHost-Configs mit alten Ports. Lösung: ALLE Proxy-Regeln direkt in VirtualHosts definieren, KEINE separaten conf-Dateien verwenden.
2. Apache reload ist unzuverlässig
Bei ProxyPass-Änderungen: systemctl restart apache2 (nicht reload!) Grund: reload cached manchmal alte Backend-Ports.
3. SystemD Override-Dateien prüfen
Prüfen mit: systemctl cat service.service YT4K Beispiel: Override in /etc/systemd/system/yt4k.service.d/90-force.conf änderte Port auf 8443.
4. Backup-Dateien aus sites-enabled entfernen
Dateien wie .bak, .tmp, .new werden von Apache gelesen und verursachen Konflikte.
WICHTIGSTE DIENSTE & PORTS
Über Apache Proxy (HTTPS):
- MediaWiki:
https://dergagi.changeip.org/w/ - YT4K:
https://dergagi.changeip.org/yt4k/ - Ombi:
https://dergagi.changeip.org/ombi/
Direkt HTTP (ohne Proxy):
- Emby:
http://dergagi.changeip.org:8096 - n8n:
http://dergagi.changeip.org:5678 - Grafana:
http://dergagi.changeip.org:3000 - HomeBox:
http://dergagi.changeip.org:3100 - Koel:
http://dergagi.changeip.org:6680 - Uptime Kuma:
http://dergagi.changeip.org:3001
Traefik (Nextcloud):
- Nextcloud:
https://nc.dergagi9.duckdns.org:8444
TROUBLESHOOTING ESSENTIALS
503 Service Unavailable über Apache Proxy
Diagnose:
bash
# Backend läuft?
systemctl status yt4k.service
ss -tlnp | grep :8443
# Backend direkt erreichbar?
curl http://127.0.0.1:8443/
# Apache Config korrekt?
grep "ProxyPass.*yt4k" /etc/apache2/sites-enabled/*.conf
# Alte conf-enabled Dateien?
ls /etc/apache2/conf-enabled/ | grep yt4k
Lösung:
bash
# Alte conf-enabled deaktivieren
a2disconf yt4k.conf
systemctl restart apache2 # RESTART!
Browser erzwingt HTTPS für HTTP-Ports
Ursache: HSTS im Browser-Cache Lösung Chrome: chrome://net-internals/#hsts → Domain dergagi.changeip.org löschen Alternative: Private/Incognito Mode
Apache Config Änderungen
Checkliste:
- Backup:
cp config.conf config.conf.backup-$(date +%Y%m%d) - Änderung vornehmen
- Test:
apache2ctl configtest - RESTART:
systemctl restart apache2(nicht reload!) - Dienst testen:
curl -k https://dergagi.changeip.org/path/
SYSTEMD SERVICES (NATIVE/PYTHON)
YT4K Upscaler:
- Port: 8443 (NICHT 8010!)
- Service:
yt4k.service - Path:
/srv/yt4k/ - User: www-data
n8n:
- Port: 5678
- Service:
n8n.service - Path:
/opt/n8n/ - User: gagi
Emby:
- Port: 8096
- Service:
emby-server.service - Path:
/opt/emby-server/,/var/lib/emby/ - User: emby
Heatmap:
- Port: 8020
- Service:
heatmap8020.service - Path:
/opt/heatmap8020/ - User: root
DOCKER WICHTIGSTE CONTAINER
Host Network (direkt):
- homeassistant (Port 8123)
- grafana-system (Port 3000)
- prometheus-system (Port 9090)
Bridge mit Port-Mapping:
- nextcloud-app (8086:80, über Traefik 8444)
- mediawiki (8088:80)
- koel (6680:80)
- ombi (3579:3579)
- uptime-kuma (3001:3001)
Traefik + Nextcloud:
- Netzwerk:
proxy(172.27.0.0/16) - traefik-nc: Port 8444 (HTTPS), 81 (HTTP), 8082 (Dashboard)
- nextcloud-app: In zwei Netzwerken (
proxy+nextcloud_nextcloud-net)
SSL/TLS ZERTIFIKATE
Apache (Certbot):
- Domain:
dergagi.changeip.org - Path:
/etc/letsencrypt/live/dergagi.changeip.org/ - Gültig bis: 29.12.2025
Traefik (ACME):
- Domain: Wildcard
*.dergagi9.duckdns.org - Path:
/srv/traefik/letsencrypt/acme.json - Gültig bis: 18.11.2025
WICHTIGE PFADE
Apache Configs: /etc/apache2/sites-enabled/
Apache Logs: /var/log/apache2/error.log
Docker Compose: /srv/*/docker-compose.yml
SystemD Services: /etc/systemd/system/*.service
Backups: /mnt/nvme_backup/ (21 Versionen)
Archive: /root/apache-archive-*/
QUICK REFERENCE COMMANDS
bash
# Apache
apache2ctl configtest && systemctl restart apache2
apache2ctl -S # VirtualHosts anzeigen
# Port prüfen
ss -tlnp | grep :PORT
curl http://127.0.0.1:PORT/
# Docker
docker ps
docker logs -f CONTAINER
docker compose restart
# SystemD
systemctl status SERVICE
systemctl cat SERVICE # Inkl. Overrides!
journalctl -u SERVICE -f
REGELN FÜR ÄNDERUNGEN
- NIE conf-enabled Dateien für Proxies verwenden
- IMMER ProxyPass in beiden VirtualHosts (catchall + website) definieren
- IMMER
systemctl restart apache2bei Proxy-Änderungen (nicht reload) - IMMER
systemctl catprüfen bei SystemD-Services (Override-Dateien!) - IMMER Backend direkt testen bevor Proxy konfiguriert wird
HSTS-HINWEIS
Aktuell: KEIN HSTS-Header aktiv (bewusst deaktiviert) Grund: Flexible Nutzung von HTTP-Ports (3000, 5678, 6680, etc.) Wenn Browser HTTPS erzwingt: Browser-Cache löschen (siehe Troubleshooting)
Version: 1.0 Kurzfassung | Datum: 01.10.2025 | Basis: Vollständige Dokumentation v1.0
STORE2 NETZWERK-ARCHITEKTUR DOKUMENTATION Vollständig
Version: 1.0 | Datum: 01.10.2025 | Host: STORE2 (Debian 13 Cinnamon)
EXECUTIVE SUMMARY
STORE2 betreibt eine hybride Infrastruktur mit drei parallelen Zugriffswegen, die sorgfältig getrennt sein müssen:
- Apache Reverse Proxy (Port 443/80) → Hauptdomain
dergagi.changeip.org - Traefik Reverse Proxy (Port 8444/81) → Nextcloud
nc.dergagi9.duckdns.org:8444 - Direkte Port-Zugriffe → Dienste ohne Proxy (HTTP)
Die Komplexität entsteht durch die Kombination aus:
- 2 Apache VirtualHosts auf Port 443 (catchall + named)
- Docker-basierte Dienste (24 Container)
- SystemD-Services (4 native/Python-Apps)
- Zwei separate Let's Encrypt Systeme (Apache/Certbot + Traefik/ACME)
Kritische Erkenntnis aus heutigem Troubleshooting: Globale Apache conf-enabled Dateien überschreiben VirtualHost-Konfigurationen. Proxy-Routen müssen direkt in VirtualHosts definiert werden, NICHT in separaten conf-Dateien.
1. NETZWERK-ARCHITEKTUR ÜBERSICHT
1.1 Die drei Zugriffswege
Internet
|
|-- Port 443/80 --> Apache --> Reverse Proxy --> Interne Dienste
|
|-- Port 8444 --> Traefik --> Nextcloud (Port 8086)
|
|-- Direkte Ports (3000, 5678, 6680, 8092, etc.) --> HTTP-Dienste
1.2 Apache VirtualHost Struktur (Port 443)
Apache nutzt zwei VirtualHosts, die beide auf Port 443 lauschen:
A) 000-catchall-443.conf (Default VirtualHost)
- ServerName:
catchall.local - Funktion: Fängt Requests ohne spezifischen Host ab
- ProxyPass:
/w/(MediaWiki),/yt4k/,/ombi/ - Problem: Ist als
*default*konfiguriert, wird deshalb bevorzugt behandelt
B) 000-website-dergagi-443.conf (Named VirtualHost)
- ServerName:
dergagi.changeip.org - Funktion: Expliziter Host-Match
- ProxyPass:
/yt4k/,/api,/ombi/,/w/,/cwa - Enthält zusätzlich: MediaWiki Rewrite-Rules, PHP-FPM Handler
Wichtig: Beide VirtualHosts haben identische ProxyPass-Regeln für /yt4k/ und /ombi/, um sicherzustellen, dass die Dienste unabhängig vom gewählten VirtualHost erreichbar sind.
1.3 Port 444 - Home Assistant
Separater VirtualHost auf Port 444 für Home Assistant:
- URL:
https://dergagi.changeip.org:444 - Proxy zu:
localhost:8123 - Besonderheit: WebSocket-Support für
/api/websocket
2. DIENSTE-ÜBERSICHT
2.1 Vollständige Dienste-Tabelle
2.2 Port-Belegung (alle lauschenden Ports)
80 Apache HTTP (Redirect zu HTTPS)
81 Traefik HTTP (Let's Encrypt Challenge)
443 Apache HTTPS (Hauptdomain)
444 Apache HTTPS (Home Assistant)
3000 Grafana System Monitoring
3001 Uptime Kuma
3100 HomeBox Inventar
3579 Ombi (intern, Apache Proxy)
5678 n8n Automation
6680 Koel Music Streaming
8020 Heatmap Generator
8080 LibreSpeed
8082 Traefik Dashboard
8084 Calibre-Web (intern, Apache Proxy)
8086 Nextcloud App (intern, Traefik Proxy)
8087 InfluxDB (Speedtest Daten)
8088 MediaWiki (intern, Apache Proxy)
8092 Speedtest Tracker
8096 Emby Media Server
8123 Home Assistant (intern, Apache Proxy Port 444)
8443 YT4K Upscaler (intern, Apache Proxy)
8444 Traefik HTTPS (Nextcloud)
9000 Portainer (nur Tailscale + localhost)
9090 Prometheus System
9100 Node Exporter
19998 Netdata
3. APACHE REVERSE PROXY SETUP
3.1 Haupt-Konfigurationsdateien
Aktive sites-enabled:
000-catchall-443.conf → Default VirtualHost, Port 443
000-website-dergagi-443.conf → Named VirtualHost, Port 443
00-redirect-80.conf → HTTP zu HTTPS Redirect
homeassistant-444.conf → Home Assistant, Port 444
le-webroot-80.conf → Let's Encrypt Webroot
Wichtig: Keine conf-enabled Dateien mehr aktiv! Alle Proxy-Regeln sind direkt in den VirtualHosts definiert.
3.2 Apache Proxy-Routen (Port 443)
000-catchall-443.conf ProxyPass-Regeln:
apache
ProxyPass /w/ http://127.0.0.1:8088/
ProxyPassReverse /w/ http://127.0.0.1:8088/
ProxyPass /yt4k/ http://127.0.0.1:8443/ retry=0
ProxyPassReverse /yt4k/ http://127.0.0.1:8443/
ProxyPass /ombi/ http://127.0.0.1:3579/ombi/ retry=0
ProxyPassReverse /ombi/ http://127.0.0.1:3579/ombi/
000-website-dergagi-443.conf ProxyPass-Regeln:
apache
ProxyPass /api http://127.0.0.1:8443/api retry=0
ProxyPassReverse /api http://127.0.0.1:8443/api
ProxyPass /yt4k/ http://127.0.0.1:8443/ retry=0
ProxyPassReverse /yt4k/ http://127.0.0.1:8443/
ProxyPass /ombi/ http://127.0.0.1:3579/ombi/ retry=0
ProxyPassReverse /ombi/ http://127.0.0.1:3579/ombi/
ProxyPass /w/ http://127.0.0.1:8088/
ProxyPassReverse /w/ http://127.0.0.1:8088/
<Location /cwa>
ProxyPass http://127.0.0.1:8084/
ProxyPassReverse http://127.0.0.1:8084/
</Location>
Zusätzliche Features:
- MediaWiki Short URLs:
/wiki/→/w/index.php?title= - PHP-FPM Handler für
.phpDateien - Security Headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy)
- Kein HSTS-Header (bewusst deaktiviert für flexible Port-Nutzung)
3.3 SSL/TLS Konfiguration (Apache)
Zertifikat: /etc/letsencrypt/live/dergagi.changeip.org/
- Typ: Let's Encrypt (via Certbot)
- Ausgestellt: 30. September 2025
- Gültig bis: 29. Dezember 2025
- Erneuerung: Automatisch via Certbot
SSL-Engine:
apache
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/dergagi.changeip.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/dergagi.changeip.org/privkey.pem
Genutzt von:
- 000-catchall-443.conf
- 000-website-dergagi-443.conf
- homeassistant-444.conf
4. TRAEFIK REVERSE PROXY (NEXTCLOUD)
4.1 Traefik v3.5 Setup
Container: traefik-nc Image: traefik:v3.5 Netzwerk: proxy (Bridge, 172.27.0.0/16)
Port-Mapping:
8444 (extern) → 443 (intern) HTTPS für Nextcloud
81 (extern) → 80 (intern) HTTP für Let's Encrypt Challenge
8082 (extern) → 8080 (intern) Traefik Dashboard
4.2 Nextcloud Docker Compose
Container: nextcloud-app Image: nextcloud:31.0.9 Port: 8086:80 (intern)
Netzwerke:
nextcloud_nextcloud-net(Bridge, 172.26.0.0/16) → Verbindung zur DBproxy(Bridge, 172.27.0.0/16) → Verbindung zu Traefik
Environment Variables:
yaml
OVERWRITEPROTOCOL: https
OVERWRITEHOST: nc.dergagi9.duckdns.org:8444
NEXTCLOUD_TRUSTED_DOMAINS: nc.dergagi9.duckdns.org:8444
TRUSTED_PROXIES: 172.16.0.0/12 192.168.0.0/16 10.0.0.0/8
Traefik Labels:
yaml
traefik.enable: true
traefik.http.routers.nextcloud.rule: Host(`nc.dergagi9.duckdns.org`)
traefik.http.routers.nextcloud.entrypoints: websecure
traefik.http.routers.nextcloud.tls: true
traefik.http.routers.nextcloud.tls.certresolver: letsencrypt
traefik.http.services.nextcloud.loadbalancer.server.port: 80
4.3 SSL/TLS (Traefik)
Zertifikat: Wildcard *.dergagi9.duckdns.org
- Typ: Let's Encrypt (via Traefik ACME)
- Speicherort:
/srv/traefik/letsencrypt/acme.json - Ausgestellt: 20. August 2025
- Gültig bis: 18. November 2025
- Erneuerung: Automatisch via Traefik
Zugriff:
https://nc.dergagi9.duckdns.org:8444
5. DOCKER CONTAINER ÜBERSICHT
5.1 Container nach Netzwerk
Host Network (direkter Host-Zugriff):
homeassistant(Home Assistant Core)grafana-system(System Monitoring, Port 3000)prometheus-system(Metriken, Port 9090)node-simple(Node Exporter, Port 9100)addon_5c53de3b_esphome(ESPHome Add-on)addon_core_matter_server(Matter Server)addon_a0d7b954_tailscale(Tailscale Add-on)hassio_multicast(Multicast DNS)
Bridge Networks:
bridge(172.17.0.0/16): homebox, ombi, hassio_supervisorproxy(172.27.0.0/16): traefik-nc, nextcloud-appnextcloud_nextcloud-net(172.26.0.0/16): nextcloud-app, nextcloud-dbkoel_default(172.23.0.0/16): koel, koel-dbmediawiki-clean-final_default(192.168.80.0/20): mw-clean-final, mw-clean-final-dbcwa_default(172.20.0.0/16): calibre-web-automateduptime-kuma_default(192.168.32.0/20): uptime-kumaspeedtest-tracker-new_default(172.24.0.0/16): speedtest-tracker-new, speedtest-influxdb-v2portainer-net(192.168.160.0/20): portainerhassio(172.30.32.0/23): Home Assistant Add-ons
5.2 Kritische Container mit Restart-Policy
Alle produktiven Container nutzen: restart: unless-stopped
Ausnahmen (restart: no):
- Home Assistant Add-ons (werden von Supervisor verwaltet)
6. SYSTEMD SERVICES (NATIVE/PYTHON)
6.1 Emby Media Server
Type: Native Debian Installation (Version 4.9.1.31) Port: 8096 (HTTP), 8920 (HTTPS, nicht konfiguriert) Service: emby-server.service User: emby
Pfade:
- Binary:
/opt/emby-server/ - Daten:
/var/lib/emby/
FFmpeg Override:
ExecStart=/opt/emby-server/system/EmbyServer -programdata /var/lib/emby \
-ffdetect /opt/emby-server/bin/ffdetect \
-ffmpeg /usr/bin/ffmpeg \
-ffprobe /usr/bin/ffprobe
6.2 YT4K Upscaler (FastAPI)
Type: Python FastAPI + Uvicorn Port: 8443 (HTTP) Service: yt4k.service User: www-data WorkingDirectory: /srv/yt4k/
ExecStart (via override):
bash
/srv/yt4k/.venv/bin/uvicorn --app-dir /srv/yt4k app:app \
--host 0.0.0.0 --port 8443 --workers 2 --log-level info
Wichtig: Läuft auf 0.0.0.0:8443, nicht auf 127.0.0.1:8010 (alte Config)!
6.3 n8n Automation
Type: Node.js App Port: 5678 (HTTP) Service: n8n.service User: gagi WorkingDirectory: /opt/n8n/
Environment:
N8N_PORT=5678
N8N_HOST=0.0.0.0
N8N_USER_FOLDER=/opt/n8n
ExecStart:
bash
/usr/local/bin/n8n
6.4 Heatmap Generator (FastAPI)
Type: Python FastAPI + Uvicorn Port: 8020 (HTTP) Service: heatmap8020.service User: root WorkingDirectory: /opt/heatmap8020/
Environment:
MPLBACKEND=Agg # Matplotlib ohne Display
ExecStart:
bash
/opt/heatmap8020/.venv/bin/uvicorn app:app \
--host 0.0.0.0 --port 8020 --proxy-headers
7. TAILSCALE INTEGRATION
IP: 100.108.194.126 Hostname: store2 Status: Active
Verwendung:
- Portainer:
http://100.108.194.126:9000(einziger Zugriff) - Keine Tailscale Serve/Funnel Konfiguration aktiv
Andere Tailscale Nodes:
myth(Windows, 100.98.212.121) - Activesilvaner(Windows, 100.120.162.83) - Active- Weitere Nodes offline
8. MONITORING & METRICS
8.1 Grafana System Monitoring
Container: grafana-system Port: 3000 (Host Network) Datenquelle: Prometheus System (Port 9090)
Metriken:
- CPU, RAM, Disk I/O via
node-exporter-system(Port 9100) - Direkt vom Host via Host Network
8.2 Uptime Kuma
Container: uptime-kuma Image: louislam/uptime-kuma:1.23.13-alpine Port: 3001 Daten: /opt/uptime-kuma/data
Funktion:
- HTTP(s) Checks für alle kritischen Dienste
- Ping Tests
- E-Mail Alerts bei Ausfällen
8.3 Netdata Real-Time Monitoring
Type: Native Installation Port: 19998 Zugriff: http://dergagi.changeip.org:19998
Metriken:
- Real-time System Performance
- Container Monitoring
- Network Traffic
- Disk I/O
9. BACKUP & REDUNDANZ
9.1 NVMe System Backup
Timer: nvme-backup.timer Schedule: Täglich um 03:08 Uhr Technologie: rsync mit --link-dest
Quellen: System-Partitionen (NVMe) Ziel: /mnt/nvme_backup Aufbewahrung: 21 Versionen (Hard-Link-Snapshots)
Wichtig: --one-file-system verhindert Backup der 113TB RAID-Arrays!
9.2 RAID Monitoring
Arrays:
/data(RAID6)/data2(RAID6)
Monitoring:
mdadm(/etc/mdadm/mdadm.conf)smartd(/etc/smartd.conf)- Alert-Script:
/usr/local/sbin/health-alert.sh
Besonderheit: SMART-Fehler ID 197 (CurrentPendingSector) wird ignoriert (RAID-typisch, nicht kritisch).
10. TROUBLESHOOTING GUIDE
10.1 Häufige Probleme & Lösungen
Problem: Dienst über Apache Proxy gibt 503 Service Unavailable
Symptome:
503 Service Unavailable
AH00957: http: attempt to connect to 127.0.0.1:PORT failed
Ursachen & Lösungen:
- Backend läuft nicht:
bash
# Prüfen
systemctl status yt4k.service
docker ps | grep mediawiki
# Starten
systemctl start yt4k.service
docker start mw-clean-final
- Falscher Port in Apache Config:
bash
# Prüfen welcher Port tatsächlich lauscht
ss -tlnp | grep :8443
# Apache Config prüfen
grep "ProxyPass.*yt4k" /etc/apache2/sites-enabled/*.conf
# Port korrigieren und neu laden
systemctl reload apache2
- Globale conf-enabled Datei überschreibt VirtualHost:
bash
# Prüfen
ls /etc/apache2/conf-enabled/
# Alte yt4k-*.conf Dateien deaktivieren
a2disconf yt4k.conf
systemctl restart apache2 # RESTART, nicht reload!
Problem: Browser erzwingt HTTPS für HTTP-Ports (HomeBox, Koel, n8n)
Symptome:
Browser zeigt "Sichere Verbindung fehlgeschlagen" für:
http://dergagi.changeip.org:3100 (HomeBox)
http://dergagi.changeip.org:6680 (Koel)
Ursache: HSTS im Browser-Cache
Lösung:
Chrome/Edge:
- Öffne
chrome://net-internals/#hsts - "Delete domain security policies"
- Domain:
dergagi.changeip.org - [Delete]
Firefox:
about:preferences#privacy- "Cookies und Website-Daten"
- "Daten verwalten..."
- Suche:
dergagi.changeip.org - "Ausgewählte entfernen"
Alternative: Nutze Private/Incognito Mode
Problem: MediaWiki API nicht erreichbar
Symptome:
/w/api.php gibt 404 oder wird zu falscher URL weitergeleitet
Lösung:
bash
# Prüfe RewriteRules
grep "RewriteRule.*api.php" /etc/apache2/sites-enabled/*.conf
# Sollte sein:
# RewriteRule ^/w/(api\.php|load\.php|rest\.php)$ - [L]
Problem: Nextcloud über Port 8444 nicht erreichbar
Symptome:
https://nc.dergagi9.duckdns.org:8444 → Connection refused
Diagnose:
bash
# Traefik läuft?
docker ps | grep traefik-nc
# Port 8444 lauscht?
ss -tlnp | grep :8444
# Traefik Logs
docker logs traefik-nc --tail 50
# Nextcloud Container läuft?
docker ps | grep nextcloud-app
# Netzwerk korrekt?
docker inspect nextcloud-app | grep -A 10 Networks
Lösung:
bash
cd /srv/nextcloud
docker compose restart
10.2 Apache Reload vs Restart
WICHTIG: Bei Proxy-Änderungen immer RESTART, nicht reload!
bash
# NUR für Header/Rewrite-Änderungen:
systemctl reload apache2
# Für ProxyPass-Änderungen:
systemctl restart apache2
Grund: reload cached manchmal alte ProxyPass-Werte.
10.3 Docker Container Restart-Reihenfolge
Bei kompletten Neustarts (z.B. nach Server-Reboot):
- Datenbank-Container zuerst:
bash
docker start nextcloud-db mw-clean-final-db koel-db
sleep 5
- Dann App-Container:
bash
docker start nextcloud-app mw-clean-final koel
- Traefik zuletzt:
bash
docker start traefik-nc
11. LESSONS LEARNED (01.10.2025)
11.1 Kritische Erkenntnisse
- Globale conf-enabled Dateien sind gefährlich:
/etc/apache2/conf-enabled/yt4k-proxy-root.confüberschrieb VirtualHost-Configs- Enthielt alte Port-Nummern (8010 statt 8443)
- Wurde trotz korrekter VirtualHost-Config verwendet
- Best Practice: Alle Proxy-Regeln direkt in VirtualHosts definieren
- Apache Reload ist nicht ausreichend:
- Bei ProxyPass-Änderungen:
systemctl restart apache2 reloadcached manchmal alte Backend-Ports- Führte zu 1 Stunde Debugging
- Bei ProxyPass-Änderungen:
- Zwei VirtualHosts auf Port 443 = Verwirrung:
000-catchall-443.confals*default*fängt viele Requests ab000-website-dergagi-443.confsollte eigentlich matchen- Lösung: Beide mit identischen ProxyPass-Regeln ausstatten
- Backup-Dateien in sites-enabled verursachen Probleme:
.bak,.tmp,.newDateien werden von Apache gelesen- Können zu Konflikten führen
- Best Practice: Nur
.confDateien in sites-enabled
- SystemD Service Override-Dateien:
/etc/systemd/system/yt4k.service.d/90-force.confüberschrieb Haupt-Service- Port 8443 statt 8010 - aber Apache zeigte auf 8010
- Immer prüfen:
systemctl cat service.service
11.2 Erfolgreiche Strategien
- Systematisches Debugging:
- Port-Listening prüfen:
ss -tlnp | grep :PORT - Backend direkt testen:
curl http://127.0.0.1:PORT/ - Apache Error Log live:
tail -f /var/log/apache2/error.log - VirtualHost Dump:
apache2ctl -S
- Port-Listening prüfen:
- Archivierung statt Löschen:
- Alle Backup-Dateien nach
/root/apache-archive-DATE/ - Ermöglicht schnelles Rollback
- 81 alte Configs archiviert, System bleibt sauber
- Alle Backup-Dateien nach
- Docker Netzwerk-Isolation:
- Nextcloud in
proxy+nextcloud_nextcloud-net - Traefik nur in
proxy - Saubere Trennung zwischen Diensten
- Nextcloud in
12. WARTUNGS-CHECKLISTEN
12.1 Vor jeder Apache-Änderung
bash
# 1. Backup der aktuellen Config
cp /etc/apache2/sites-enabled/000-website-dergagi-443.conf \
/root/000-website-dergagi-443.conf.backup-$(date +%Y%m%d-%H%M%S)
# 2. Änderung vornehmen
# 3. Config testen
apache2ctl configtest
# 4. Bei Erfolg: RESTART (nicht reload)
systemctl restart apache2
# 5. Dienste testen
curl -k https://dergagi.changeip.org/yt4k/
curl -k https://dergagi.changeip.org/w/
12.2 Neuen Dienst über Apache proxyen
- Dienst starten und Port prüfen:
bash
systemctl start new-service
ss -tlnp | grep :PORT
curl http://127.0.0.1:PORT/
- ProxyPass in BEIDEN VirtualHosts hinzufügen:
bash
nano /etc/apache2/sites-enabled/000-catchall-443.conf
# Füge hinzu:
ProxyPass /newservice/ http://127.0.0.1:PORT/ retry=0
ProxyPassReverse /newservice/ http://127.0.0.1:PORT/
nano /etc/apache2/sites-enabled/000-website-dergagi-443.conf
# Gleiche Zeilen hinzufügen
- Testen und Restart:
bash
apache2ctl configtest
systemctl restart apache2
curl -k https://dergagi.changeip.org/newservice/
- NICHT in conf-enabled anlegen!
12.3 Docker Container hinzufügen
- docker-compose.yml erstellen:
yaml
services:
newservice:
image: newservice:latest
container_name: newservice
restart: unless-stopped
ports:
- "PORT:INTERNAL_PORT"
volumes:
- ./data:/data
networks:
- newservice_net
networks:
newservice_net:
driver: bridge
- Starten:
bash
cd /srv/newservice
docker compose up -d
- Logs prüfen:
bash
docker logs newservice -f
12.4 SSL-Zertifikat erneuern (Apache)
bash
# Certbot Dry-Run
certbot renew --dry-run
# Manuelle Erneuerung
certbot renew
# Apache neu laden
systemctl reload apache2
# Zertifikat prüfen
openssl x509 -in /etc/letsencrypt/live/dergagi.changeip.org/fullchain.pem -noout -dates
12.5 Monatliche Wartung
bash
# 1. System Updates
apt update && apt upgrade -y
# 2. Docker Images aktualisieren
cd /srv/nextcloud && docker compose pull && docker compose up -d
cd /srv/mediawiki-clean-final && docker compose pull && docker compose up -d
# 3. Alte Docker Images entfernen
docker image prune -a
# 4. Logs rotieren
journalctl --vacuum-time=30d
# 5. Backup prüfen
ls -lh /mnt/nvme_backup/
# 6. RAID Status
cat /proc/mdstat
13. DATEI-PFADE REFERENZ
13.1 Apache
/etc/apache2/sites-available/ Alle verfügbaren Configs
/etc/apache2/sites-enabled/ Aktive Configs (Symlinks)
/etc/apache2/conf-available/ Zusätzliche Configs (sollte leer sein!)
/etc/apache2/conf-enabled/ Aktive zusätzliche Configs
/var/log/apache2/error.log Error Log
/var/log/apache2/access.log Access Log
/etc/letsencrypt/live/ SSL-Zertifikate
13.2 Docker
/srv/nextcloud/ Nextcloud + Traefik
/srv/mediawiki-clean-final/ MediaWiki
/srv/koel/ Koel Music
/srv/ombi/ Ombi
/srv/portainer/ Portainer
/opt/uptime-kuma/ Uptime Kuma
13.3 SystemD Services
/etc/systemd/system/yt4k.service YT4K Service
/etc/systemd/system/yt4k.service.d/ YT4K Overrides
/srv/yt4k/ YT4K Code + venv
/etc/systemd/system/n8n.service n8n Service
/opt/n8n/ n8n Daten
/etc/systemd/system/heatmap8020.service Heatmap Service
/opt/heatmap8020/ Heatmap Code + venv
/usr/lib/systemd/system/emby-server.service Emby Service (System)
/etc/systemd/system/emby-server.service.d/ Emby Overrides
/opt/emby-server/ Emby Binary
/var/lib/emby/ Emby Daten
13.4 Backups & Archive
/mnt/nvme_backup/ System Backups (21 Versionen)
/root/apache-archive-YYYYMMDD-HHMMSS/ Alte Apache Configs
/root/apache-backup-YYYYMMDD-HHMMSS/ Apache Config Backups
/root/network-fix-YYYYMMDD-HHMMSS/ Troubleshooting Logs
/root/apache-old-backups/ Archivierte Backups
14. NÄCHSTE SCHRITTE & EMPFEHLUNGEN
14.1 Kurzfristig (nächste Woche)
- Alte Docker-Verzeichnisse aufräumen:
bash
# Prüfen und löschen (wenn nicht mehr benötigt):
/srv/nextcloud-damaged-2025-09-03-112720
/srv/traefik-damaged-2025-09-03-113532
/srv/mw-docker.final-removal.20250831-111413
/opt/n8n.bak.2025-08-23-191443
- Apache Archive aufräumen:
bash
# Nach 1 Woche ohne Probleme:
rm -rf /root/apache-archive-20251001-231820
- Uptime Kuma Monitoring vervollständigen:
- Alle Dienste als Monitors hinzufügen
- E-Mail Alerts konfigurieren
14.2 Mittelfristig (nächster Monat)
- HSTS für Port 443 aktivieren:
- Nachdem Browser-Cache gelöscht ist
- Nur für
/Path, nicht global max-age=15552000(6 Monate)
- Traefik für mehr Dienste nutzen:
- YT4K, Ombi, MediaWiki könnten über Traefik laufen
- Vereinfacht SSL-Management
- Automatische Let's Encrypt Erneuerung
- 000-catchall-443.conf entfernen:
- Alle Requests sollten explizit auf 000-website-dergagi-443.conf matchen
- Vereinfacht Konfiguration
14.3 Langfristig (optional)
- Alle Docker Compose in ein zentrales File:
/srv/docker-stack/docker-compose.yml- Vereinfacht Management
- Einheitliche Netzwerk-Struktur
- Monitoring erweitern:
- Prometheus für alle Dienste
- Alertmanager für Benachrichtigungen
- Längere Metriken-Retention
- Backup-Strategie für Docker Volumes:
- Automatische Backups für Nextcloud-Daten
- MediaWiki-Datenbank Dumps
- Offsite-Backup erwägen
ANHANG A: SCHNELLREFERENZ
Apache Befehle
bash
apache2ctl configtest # Config testen
apache2ctl -S # VirtualHosts anzeigen
apache2ctl -M # Module anzeigen
systemctl restart apache2 # Komplett neu starten
systemctl reload apache2 # Config neu laden (unsicher!)
a2ensite site.conf # Site aktivieren
a2dissite site.conf # Site deaktivieren
a2enmod proxy_http # Modul aktivieren
Docker Befehle
bash
docker ps # Laufende Container
docker ps -a # Alle Container
docker logs CONTAINER # Logs anzeigen
docker logs -f CONTAINER # Logs live
docker restart CONTAINER # Container neu starten
docker compose up -d # Services starten
docker compose down # Services stoppen
docker compose restart # Services neu starten
docker network ls # Netzwerke anzeigen
docker inspect CONTAINER # Details anzeigen
SystemD Befehle
bash
systemctl status SERVICE # Status prüfen
systemctl start SERVICE # Service starten
systemctl stop SERVICE # Service stoppen
systemctl restart SERVICE # Service neu starten
systemctl cat SERVICE # Config anzeigen (inkl. Overrides)
journalctl -u SERVICE -f # Logs live
journalctl -u SERVICE -n 50 # Letzte 50 Zeilen
Netzwerk Debug
bash
ss -tlnp # Alle lauschenden Ports
ss -tlnp | grep :PORT # Spezifischer Port
curl http://127.0.0.1:PORT/ # Backend direkt testen
curl -I -k https://domain.com # Headers anzeigen
netstat -tupln # Alternative zu ss
Ende der Dokumentation
Letzte Aktualisierung: 01.10.2025, 23:30 CEST
Version: 1.0
Erstellt von: Claude (Anthropic) mit Daniel Gareis
Archiviert: /mnt/user-data/outputs/STORE2-Network-Architecture-v1.0.md
NVMe-Backup & Datenbank-Backup System - Vollständige Dokumentation v3.0
System-Übersicht
Server: STORE2 (Debian 13)
Backup-Strategien:
- OS-Level Backup: Vollständiges System-Backup via rsync + Hard Links
- Datenbank-Backup: Zwei-Schicht-Strategie für Calibre/CWA SQLite-Datenbanken
Teil 1: NVMe-Backup System (OS-Level)
Grundlegende Eigenschaften
- Zweck: Tägliche vollständige OS-Level Disaster Recovery Backups
- Methode: rsync mit Hard Link Deduplication und
--one-file-system - Backup-Größe: ~130GB pro Generation (apparent), ~37GB real durch Hard Links
- Retention: 21 Tage (daily.0 bis daily.20)
- Zeitplan: Täglich um 03:05 Uhr (±5min Randomisierung)
Hardware-Konfiguration
- Quelle: NVMe System-Laufwerk (/)
- Ziel:
/mnt/nvme_backup- 1TB HDD (/dev/sdar1, ext4, Label: NVME_BACKUP) - Kapazität: 21 Backup-Generationen bei ~85% HDD-Auslastung (geschätzt 777GB)
Hard Link Backup-Technologie
Funktionsweise der Deduplication
- Erste Generation (daily.0): Vollständiges Backup (~130GB apparent)
- Folge-Generationen: Nur geänderte/neue Dateien verbrauchen Speicherplatz
- Unveränderte Dateien: Hard Links zur vorherigen Generation (0 Byte zusätzlich)
- Gemessene Effizienz: 98-99% aller Dateien sind Hard-Linked zwischen Generationen
Realistische Speichernutzung
daily.0: 130G apparent / 7.4GB real (neueste Generation)
daily.1: 126G apparent / 85.5GB real (1 Tag alt)
daily.2: 126G apparent / 4.1GB real (2 Tage alt)
Durchschnitt: ~37GB real pro Generation
21 Generationen: ~777GB total (statt 2.7TB bei Vollbackups)
Pseudo-Inkrementelles System
- Jede Generation erscheint als vollständiges Filesystem (130GB)
- Tatsächlicher Speicherverbrauch nur für Änderungen
- Wiederherstellung jeder Generation als komplettes System möglich
- Keine Abhängigkeiten zwischen Generationen (jede ist vollständig)
KRITISCH: Verzeichnis-Timestamps verstehen
WICHTIG: Die Timestamps der daily.* Verzeichnisse sind NICHT die Backup-Zeiten!
Warum alle Verzeichnisse das gleiche Datum zeigen:
mvinnerhalb desselben Filesystems ändert KEINE Directory-mtimes- Das Skript macht:
mv daily.0 daily.1,mv daily.1 daily.2, etc. - Die Directory-Timestamps bleiben beim ersten Erstellen eingefroren
Wo sind die ECHTEN Backup-Zeiten?
- Log-Dateien:
/mnt/nvme_backup/_logs/run-YYYY-MM-DD_HH-MM-SS.log - Datei-mtimes: Dateien INNERHALB der Backups haben korrekte mtimes
- SystemD Journal:
journalctl -u nvme-backup.service
Backup-Alter prüfen:
bash
ls -lth /mnt/nvme_backup/_logs/ | head
Software-Komponenten
SystemD Services
- Service:
nvme-backup.service- OneShot-Service für Backup-Ausführung - Timer:
nvme-backup.timer- Tägliche Ausführung um 03:05 Uhr (±5min) - Mail-Services:
nvme-backup-mail@success.service- Erfolgs-Benachrichtigungnvme-backup-mail@failure.service- Fehler-Alarm
Scripts und Pfade
- Backup-Script:
/usr/local/sbin/nvme-backup(KEEP=21) - Mail-Script:
/usr/local/sbin/nvme-backup-mailer - Log-Verzeichnis:
/mnt/nvme_backup/_logs/ - Backup-Verzeichnisse:
/mnt/nvme_backup/daily.0bisdaily.20
Backup-Ablauf im Detail
Phase 1: Rotation (1-15 Minuten)
Das Skript rotiert die Verzeichnisse rückwärts:
- Lösche
daily.21(falls vorhanden) -rm -rfdauert lange! - Verschiebe
daily.20→daily.21 - Verschiebe
daily.19→daily.20 - ... bis
daily.0→daily.1 - Erstelle leeres
daily.0
WICHTIG: Das Löschen von daily.21 kann 5-15 Minuten dauern (~49GB Hard-Links). Der Prozess "rm" erscheint in top mit hoher CPU-Last - das ist NORMAL!
Phase 2: rsync (15-60 Minuten)
rsync kopiert von / nach daily.0 mit:
--link-dest=daily.1(Hard Links für unveränderte Dateien)--delete(entfernt gelöschte Dateien aus daily.0)--one-file-system(ignoriert/data,/data2)- Fortschritt: Im Log
/mnt/nvme_backup/_logs/run-*.log
Phase 3: Fertigstellung
Script loggt "Backup OK" und beendet sich mit Exit 0.
rsync-Parameter
Vollständiger Befehl:
bash
rsync -aAXH --delete --numeric-ids --info=progress2 --one-file-system \
--link-dest=daily.1 / /mnt/nvme_backup/daily.0
Kritische Parameter:
-a: Archive-Mode (rlptgoD) - Permissions, Timestamps, etc.-A: ACLs preservieren-X: Extended Attributes preservieren-H: Hard Links im Quell-System preservieren--delete: Gelöschte Dateien auch aus Backup entfernen--numeric-ids: UIDs/GIDs als Zahlen (nicht Namen)--one-file-system: KRITISCH! Verhindert Backup der RAID-Mounts--link-dest: Hard Links zu daily.1 für unveränderte Dateien
Exclude-Liste
Das Skript schließt folgende Pfade aus:
/proc/- Kernel-Prozess-Dateisystem/sys/- Kernel-System-Dateisystem/dev/- Device-Dateien/run/- Runtime-Daten/tmp/- Temporäre Dateien/data/- RAID-Mount md125 (XFS, 52TB)/data2/- RAID-Mount md126 (EXT4, 61TB)/lost+found- Dateisystem-Recovery/mnt/nvme_backup/*- Backup-Ziel selbst
Backup-Inhalt
Vollständig gesichert:
/usr(21GB) - System-Binaries/etc(399MB) - Konfigurationen/boot(417MB) - Kernel, Bootloader/var(42GB) - Docker-Container, Emby-Metadaten, Systemlogs/home(10.5GB) - User-Daten/srv(9.5GB) - Service-Daten (Docker-Compose-Projekte)/opt(1.5GB) - Zusatz-Software/root(20GB) - Admin-Scripts und Configs
KRITISCH: rsync Exitcode 24
Problem: rsync gibt Exitcode 24 zurück, wenn Dateien während des Backups verschwinden.
Ursachen (normal bei Live-Systemen):
- Docker-Container schreiben/löschen Log-Dateien
- Browser-Caches werden geleert
- Temporäre Dateien verschwinden
- Log-Rotation läuft parallel
Lösung (seit 2025-10-11 implementiert): Exit-Codes 0, 23, 24 werden als Erfolg gewertet. Andere Exit-Codes lösen Fehler-Mail aus.
Tolerierte Exit-Codes:
0: Perfekter Durchlauf23: Partial transfer (z.B. Permission-Probleme bei einzelnen Dateien)24: Some files vanished (normale Live-System-Situation)
Mail-Benachrichtigungen
SMTP-Konfiguration
- Provider: GMX (mail.gmx.net:587, TLS)
- Absender: dergagi@gmx.de
- Empfänger: daniel.gareis@gmail.com
- Auth:
/etc/msmtprc(chmod 600)
Mail-Inhalt bei Erfolg
- Backup-Statistiken (apparent/real size, übertragene Datenmenge)
- Speicherplatz-Metriken (belegt/verfügbar/Prozent)
- Retention-Info (Anzahl Generationen, geschätzte Kapazität)
- System-Status (nächster Backup-Termin, RAID-Status)
- Performance-Daten (Log-Größe, Dauer)
Mail-Inhalt bei Fehler
- Error-Details aus journalctl
- Backup-Festplatten-Status
- Log-Pfad für weitere Diagnose
- RAID-Status
Teil 2: Datenbank-Backup System (SQLite)
Übersicht
Zweck: Zwei-Schicht-Backup-Strategie für Calibre/Calibre-Web Datenbanken
Problem: /data wird via --one-file-system vom OS-Backup ausgeschlossen
Lösung: Separate DB-Backups mit unterschiedlichen Retention-Zeiten
Warum separates DB-Backup?
Hintergrund:
- Calibre-Bibliothek liegt auf
/data/ebooks/(257GB E-Books + 50MB metadata.db) - Calibre-Web Config liegt auf
/data/ebooks-config/(87GB Caches + 5MB app.db) /dataist ein separates RAID6-Array (52TB) und wird vom NVMe-Backup ausgeschlossen
Backup-Strategie:
- E-Books selbst: NICHT gebackupt (257GB, zu groß, regenerierbar aus Quellen)
- Datenbanken: KRITISCH für Recovery, nur ~70MB
- Best Practice: SQLite-DBs benötigen konsistente Backups via
sqlite3 .backup
Zwei-Schicht-Architektur
Layer 1: Daily Safety Backup (NVMe)
Zweck: Schnelles Recovery bei CWA-Problemen oder Fehlkonfiguration
Eigenschaften:
- Ziel:
/mnt/nvme_backup/_data_dbs/ - Retention: 7 Tage (tägliche Ordner: YYYY-MM-DD)
- Zeitplan: Täglich um 03:30 Uhr (nach Haupt-Backup)
- Größe: ~70MB pro Backup
- Service:
daily-db-backup.service+daily-db-backup.timer
Gebackupte Dateien:
calibre_metadata-/data/ebooks/metadata.db(50MB)calibre_prefs-/data/ebooks/metadata_db_prefs_backup.json(16KB)cwa_app-/data/ebooks-config/app.db(5MB)cwa_main-/data/ebooks-config/cwa.db(15MB)
Backup-Methode:
- SQLite-DBs:
sqlite3 $src ".backup $dest"+ Integrity-Check - JSON-Dateien: Simple
cp -p
Layer 2: Weekly Archive Backup (RAID→RAID)
Zweck: Langzeit-Absicherung gegen Hardware-Fehler, tiefere Historie
Eigenschaften:
- Ziel:
/data2/db-archive/ - Retention: 4 Wochen (Ordner: YYYY-Wxx)
- Zeitplan: Sonntag 04:00 Uhr
- Größe: ~103MB pro Archiv (inkl. Backups + Logs)
- Service:
weekly-archive-backup.service+weekly-archive-backup.timer
Gebackupte Dateien (erweitert):
- Alle aus Daily Backup PLUS:
calibre_metadata_backup-/data/ebooks/metadata.db.backup-*(Wildcard)cwa_app_backup-/data/ebooks-config/app.db.backup-*(Wildcard)cwa_logs-/data/ebooks-config/calibre-web.log*(Diagnose)
Vorteile:
- RAID-zu-RAID: Besserer Hardware-Schutz als NVMe→HDD
- Wildcard-Gruppen: Automatisches Backup aller DB-Versionen
- Wöchentlich: Weniger Overhead, längere Geschichte
Software-Komponenten
SystemD Services (Daily Backup)
- Service:
daily-db-backup.service - Timer:
daily-db-backup.timer(03:30 Uhr täglich) - Script:
/usr/local/sbin/daily-db-backup - Logs:
/mnt/nvme_backup/_data_dbs/_logs/
SystemD Services (Weekly Backup)
- Service:
weekly-archive-backup.service - Timer:
weekly-archive-backup.timer(Sonntag 04:00 Uhr) - Script:
/usr/local/sbin/weekly-archive-backup - Logs:
/data2/db-archive/_logs/
Backup-Ablauf
Daily Backup (03:30 Uhr)
- Backup-Ordner erstellen:
/mnt/nvme_backup/_data_dbs/YYYY-MM-DD/ - Für jede Datenbank:
- SQLite:
sqlite3 .backup+PRAGMA integrity_check - JSON:
cp -pmit Timestamp-Erhalt
- SQLite:
- Retention: Löscht Backups älter als 7 Tage
- Log: Schreibt detailliertes Log nach
_logs/
Weekly Backup (Sonntag 04:00 Uhr)
- Archiv-Ordner erstellen:
/data2/db-archive/YYYY-Wxx/ - Haupt-DBs backupen (wie Daily)
- Wildcard-Gruppen backupen:
- Sucht alle
*.db.backup-*Dateien - Kopiert in Unterordner
- Sucht alle
- Logs archivieren: Alle
calibre-web.log*für Diagnose - Retention: Löscht Archive älter als 4 Wochen
- Speicherplatz-Check: Zeigt
/data2Belegung
Wichtige Unterschiede zu OS-Backup
Service-Kontrolle
Status prüfen
bash
# Daily Backup
systemctl status daily-db-backup.timer
systemctl status daily-db-backup.service
ls -lth /mnt/nvme_backup/_data_dbs/_logs/ | head
# Weekly Backup
systemctl status weekly-archive-backup.timer
systemctl status weekly-archive-backup.service
ls -lth /data2/db-archive/_logs/ | head
Manueller Start
bash
# Daily Backup manuell ausführen
systemctl start daily-db-backup.service
# Weekly Backup manuell ausführen
systemctl start weekly-archive-backup.service
Backup-Struktur anzeigen
bash
# Daily Backups (letzte 7)
ls -lh /mnt/nvme_backup/_data_dbs/
# Weekly Archive (letzte 4)
ls -lh /data2/db-archive/
# Detaillierter Inhalt eines Backups
tree /mnt/nvme_backup/_data_dbs/2025-10-11/
Teil 3: Wartung und Troubleshooting
NVMe-Backup Troubleshooting
Problem 1: Service schlägt fehl mit Exit 24
Symptom: Mail "NVMe Backup FEHLGESCHLAGEN", journalctl zeigt "rsync warning: some files vanished"
Ursache: Normale Live-System-Situation
Lösung: Seit 2025-10-11 toleriert das Skript Exitcode 24. Bei älteren Skript-Versionen: Neues Skript installieren.
Problem 2: Backup-Disk voll
Symptom: rsync schlägt fehl mit "No space left on device"
Ursache: Mehr als erwartete Änderungen, oder Retention zu hoch
Lösung:
bash
# KEEP von 21 auf 18 oder 15 reduzieren
sed -i 's/KEEP=21/KEEP=18/' /usr/local/sbin/nvme-backup
# Alte Docker-Images aufräumen
docker system prune -a
# Journal bereinigen
journalctl --vacuum-time=30d
Problem 3: Backup dauert sehr lange
Symptom: rm-Prozess läuft 15+ Minuten
Ursache: daily.21 hat sehr viele Dateien (Hard-Links brauchen Zeit zum Löschen)
Lösung: Normal, abwarten. Ext4 braucht Zeit für Millionen Inodes.
Problem 4: Verzeichnis-Timestamps sind alt
Symptom: "daily.0 zeigt 7. Sep, aber heute ist 11. Okt"
Ursache: Normal! mv ändert keine Directory-mtimes
Lösung: Logs anschauen für echte Backup-Zeiten:
bash
ls -lth /mnt/nvme_backup/_logs/
DB-Backup Troubleshooting
Problem 1: SQLite Integrity-Check schlägt fehl
Symptom: Log zeigt "⚠ Integritäts-Check fehlgeschlagen"
Ursache: Korrupte Datenbank im Live-System
Lösung:
bash
# Manuelle Integritätsprüfung
sqlite3 /data/ebooks/metadata.db "PRAGMA integrity_check;"
# Bei Korruption: Von älterem Backup wiederherstellen
cp /mnt/nvme_backup/_data_dbs/2025-10-10/calibre_metadata \
/data/ebooks/metadata.db.restored
Problem 2: Wildcard-Gruppe findet keine Dateien
Symptom: Log zeigt "⚠ Keine Dateien gefunden"
Ursache: Keine Backup-Dateien vorhanden (z.B. nach CWA-Neuinstallation)
Lösung: Normal, keine Aktion nötig. Das Skript überspringt diese Gruppe.
Problem 3: Backup schlägt mit Exit 1 fehl
Symptom: Service-Status zeigt "failed"
Ursache: Quell-Datenbank nicht gefunden (z.B. Docker-Container gestoppt)
Lösung: Prüfen ob CWA läuft:
bash
docker ps | grep calibre
ls -lh /data/ebooks-config/app.db
Wiederherstellung (Recovery)
Daily Backup Recovery (schnell)
Szenario: CWA-Datenbank nach Update korrupt
bash
# 1. CWA stoppen
docker stop calibre-web
# 2. Backup wiederherstellen (gestern)
cp /mnt/nvme_backup/_data_dbs/2025-10-10/cwa_app \
/data/ebooks-config/app.db
# 3. Permissions korrigieren
chown gagi:gagi /data/ebooks-config/app.db
# 4. CWA starten
docker start calibre-web
Weekly Archive Recovery (tiefer)
Szenario: Calibre-Bibliothek korrupt, brauche Version von vor 3 Wochen
bash
# 1. Verfügbare Archive anzeigen
ls -lh /data2/db-archive/
# 2. Gewünschte Woche finden (z.B. 2025-W38)
ls -lh /data2/db-archive/2025-W38/
# 3. Backup wiederherstellen
cp /data2/db-archive/2025-W38/calibre_metadata \
/data/ebooks/metadata.db
# 4. Permissions
chown gagi:gagi /data/ebooks/metadata.db
# 5. Calibre restarten (falls Container läuft)
docker restart calibre
Vollständige System-Wiederherstellung (NVMe)
Szenario: NVMe-SSD versagt komplett
bash
# 1. Neue NVMe-SSD einbauen
# 2. Debian 13 Minimal installieren
# 3. Backup-HDD mounten
mount /dev/sdar1 /mnt/backup
# 4. System wiederherstellen
rsync -aAXH --numeric-ids /mnt/backup/daily.0/ /mnt/newsystem/
# 5. Bootloader neu installieren
chroot /mnt/newsystem
grub-install /dev/nvme0n1
update-grub
exit
# 6. Reboot
reboot
Teil 4: Performance und Kapazität
NVMe-Backup Performance
- Erstes Backup: ~130GB in 1,5 Stunden (Vollübertragung)
- Folge-Backups: ~5-40GB in 15-60 Minuten (nur Änderungen)
- CPU-Verbrauch: ~4 Minuten CPU-Zeit pro Backup
- Memory Peak: ~5.7GB während Backup
- Hard Link Effizienz: 98-99% Dateien verlinkt zwischen Generationen
- Durchschnittlicher Speicherverbrauch: 37GB real pro Generation
Rotation (rm -rf daily.21):
- Dauer: 5-15 Minuten
- CPU: 20-30% eines Cores
- Grund: Millionen Hard-Links müssen aufgelöst werden
DB-Backup Performance
- Daily Backup: ~3 Sekunden (4 Dateien, 70MB)
- Weekly Backup: ~5 Sekunden (7 Items, 103MB)
- CPU-Verbrauch: Minimal (<1% Core)
- Speicherverbrauch: ~500MB pro Woche
Kapazitäts-Management
NVMe-Backup
- Aktuelle Nutzung (typisch): 330-400GB für 21 Generationen
- Projektion 21 Tage: ~777GB (85% der 916GB HDD)
- Sicherheitspuffer: ~140GB für Variabilität
- Überwachung: Automatisch via Mail nach jedem Backup
DB-Backups
- Daily (NVMe): 7 × 70MB = ~490MB
- Weekly (RAID): 4 × 103MB = ~412MB
- Total: <1GB für beide Backup-Layer
Notfall-Maßnahmen bei Speicherknappheit (NVMe-Backup):
Option 1: Retention reduzieren
bash
sed -i 's/KEEP=21/KEEP=18/' /usr/local/sbin/nvme-backup
Option 2: System-Dateien aufräumen
bash
docker system prune -a
journalctl --vacuum-time=30d
apt clean && apt autoclean
Option 3: Manuelle Backup-Löschung
bash
rm -rf /mnt/nvme_backup/daily.20
rm -rf /mnt/nvme_backup/daily.19
Teil 5: Integration in Gesamtsystem
Drei-Schicht-Backup-Architektur
Layer 1: RAID6-Arrays (Live-Redundanz)
/data(md125, XFS, 52TB) - E-Books, Medien/data2(md126, EXT4, 61TB) - Backups, Archive- Zweck: Hardware-Redundanz gegen Festplattenausfall
Layer 2: NVMe-Backup (System-Recovery)
- Ziel:
/mnt/nvme_backup(1TB HDD) - Retention: 21 Tage
- Zweck: Vollständige OS-Wiederherstellung, 3-Wochen-Historie
Layer 3: DB-Backups (Datenbank-Schutz)
- Daily:
/mnt/nvme_backup/_data_dbs/(7 Tage) - Weekly:
/data2/db-archive/(4 Wochen) - Zweck: SQLite-konsistente Backups für Calibre/CWA
Optimierte Ressourcen-Aufteilung
- RAID-Schutz: 113TB Nutzdaten mit Hardware-Redundanz
- NVMe-Backup: 130GB System-Recovery mit 3-Wochen-Historie
- DB-Backups: <1GB für 7+28 Tage Datenbank-Historie
- Hard Link Effizienz: 777GB für 21 Vollbackups (statt 2.7TB)
Zeitplan-Koordination
03:05 Uhr: NVMe-Backup (OS-Level) startet
03:30 Uhr: Daily DB-Backup startet (nach OS-Backup)
04:00 Uhr: Weekly Archive-Backup (nur Sonntag)
Grund: DB-Backups laufen NACH dem Haupt-Backup, um Konflikte zu vermeiden.
Changelog
v3.0 (2025-10-11):
- Zwei-Schicht-DB-Backup-System hinzugefügt
- Daily Safety Backup (NVMe, 7 Tage)
- Weekly Archive Backup (RAID→RAID, 4 Wochen)
- SQLite
.backupAPI für konsistente DB-Kopien - Separate SystemD Services/Timers für DB-Backups
- Dokumentation komplett überarbeitet und erweitert
v2.0 (2025-10-11):
- Exit-Code-24-Toleranz hinzugefügt (Exit 0/23/24 = Erfolg)
- Dokumentation zu Directory-Timestamps ergänzt
- Troubleshooting-Sektion erweitert
- Performance-Charakteristika gemessen und dokumentiert
v1.0 (2025-09-07):
- Initiale 21-Tage-Retention
- Mail-Benachrichtigungen implementiert
- Hard-Link-Backup produktiv
Ende der Dokumentation v3.0
STORE2 NVME Disaster Recovery Dokumentation
Übersicht
Diese Dokumentation beschreibt die vollständige Wiederherstellung des STORE2-Servers nach einem totalen NVMe-SSD-Ausfall. Das Verfahren basiert auf täglichen rsync-Backups mit Hard-Link-Deduplication.
Systemdaten:
- Backup-System: rsync mit --link-dest (21 Generationen)
- Backup-Größe: ~118GB pro Generation
- Recovery-Zeit: 4-5 Stunden gesamt
- Besonderheit: RAID-Arrays sind mit LUKS verschlüsselt!
Voraussetzungen
Hardware-Anforderungen
- Neue NVMe SSD (Minimum: 256GB, Empfohlen: 512GB, Optimal: 1TB)
- Debian 13 Live-USB oder Installations-Medium
- Physischer Zugriff auf STORE2
- Monitor und Tastatur
- Netzwerkkabel für spätere Updates
Kritische Systeminformationen (STORE2 Stand: September 2025)
System-Partitionierung:
- /dev/nvme0n1p1: 222,6GB ext4 (Root-Partition)
- /dev/nvme0n1p5: 15,9GB swap
- Root-UUID: 0bcdb676-123c-4658-925e-9cba9ecf45df
Backup-HDD:
- Device: /dev/sdar1
- Filesystem: ext4
- Label: NVME_BACKUP
- UUID: 1c2b9b3c-f436-404a-9777-aa288477a7a8
- Mount: /mnt/nvme_backup
RAID-Arrays (VERSCHLÜSSELT mit LUKS!):
- md125: RAID6, 20 Disks, 52TB, XFS, verschlüsselt
- LUKS UUID: a54ac812-bb0e-4228-b3f7-2961fbb74ce7
- Decrypted: /dev/mapper/cr_md125
- Filesystem UUID: 9787dc50-bdd5-4054-901c-bf4657db7ab4
- Mount: /data
- md126: RAID6, 23 Disks, 61TB, EXT4, verschlüsselt
- LUKS UUID: 82d138cd-958d-42bc-b0f2-08eaa06f447d
- Decrypted: /dev/mapper/cr_md126
- Filesystem UUID: 72ee2927-2855-4ebd-a7d0-3d8f4a3450c1
- Mount: /data2
Netzwerk:
- Interface: enp0s31f6 (NICHT eth0!)
- MAC: 30:9c:23:68:bf:e8
- Hostname: STORE2
- Domain: dergagi.changeip.org
Phase 1: Vorbereitung (30 Minuten)
1.1 Hardware-Vorbereitung
- Server herunterfahren: shutdown -h now
- Stromversorgung trennen
- Defekte NVMe entfernen
- Neue NVMe einbauen
- WICHTIG: Backup-HDD (/dev/sdar1) und RAID-Disks NICHT entfernen!
1.2 Informationen dokumentieren (falls System noch läuft)
Folgende Befehle ausführen und Ausgaben sichern:
lsblk -f > /tmp/lsblk-output.txt blkid > /tmp/blkid-output.txt ip link show > /tmp/network-interfaces.txt cat /proc/mdstat > /tmp/raid-status.txt cat /etc/fstab > /tmp/fstab-backup.txt cat /etc/crypttab > /tmp/crypttab-backup.txt
Diese Dateien auf USB-Stick oder per Mail sichern!
Phase 2: Basis-Installation (45 Minuten)
2.1 Debian 13 installieren
- Von Debian 13 USB/DVD booten
- Installationstyp: Minimal (ohne Desktop-Umgebung)
- Partitionierung EXAKT wie Original:
- /dev/nvme0n1p1: 223GB ext4 für /
- /dev/nvme0n1p5: 16GB swap
- Hostname: STORE2 (wichtig!)
- Root-Passwort: Temporär (wird überschrieben)
- Netzwerk: NICHT konfigurieren
- Software: Nur "Standard-Systemwerkzeuge"
2.2 Nach Installation
- System einmal booten lassen
- Als root anmelden
- Herunterfahren: shutdown -h now
Phase 3: Recovery via Live-System (2-3 Stunden)
3.1 Live-System vorbereiten
- Von Debian Live-USB booten
- Terminal öffnen
- Root werden: sudo -i
3.2 Partitionen identifizieren
lsblk -f
Backup-HDD finden (Label: NVME_BACKUP)
blkid | grep NVME_BACKUP
Sollte zeigen: /dev/sdar1
Neue NVMe-Root finden
blkid | grep nvme0n1p1
NEUE UUID notieren!
3.3 Partitionen mounten
mkdir -p /mnt/new-system mkdir -p /mnt/backup
Neue NVMe mounten
mount /dev/nvme0n1p1 /mnt/new-system
Backup-HDD mounten (normalerweise sdar1)
mount /dev/sdar1 /mnt/backup
Prüfen
df -h | grep mnt
3.4 System wiederherstellen
WICHTIG: Dieser Schritt dauert 2-3 Stunden!
rsync -aAXHv --info=progress2
--exclude='/proc/'
--exclude='/sys/'
--exclude='/dev/'
--exclude='/run/'
--exclude='/tmp/'
--exclude='/mnt/'
/mnt/backup/daily.0/ /mnt/new-system/
Erwartete Werte:
- Dateien: ~1.7 Millionen
- Daten: ~118GB
- Dauer: 2-3 Stunden
Phase 4: System-Anpassung (1 Stunde)
4.1 Chroot vorbereiten
KRITISCH: Exakte Reihenfolge beachten!
mkdir -p /mnt/new-system/{dev,proc,sys,run}
mount --bind /dev /mnt/new-system/dev mount --bind /proc /mnt/new-system/proc mount --bind /sys /mnt/new-system/sys mount --bind /run /mnt/new-system/run mount --bind /dev/pts /mnt/new-system/dev/pts
chroot /mnt/new-system /bin/bash
Test ob chroot funktioniert
ls /root cat /etc/hostname # Sollte "STORE2" zeigen
4.2 Hardware-Anpassungen
UUID in /etc/fstab anpassen:
Neue UUID ermitteln
blkid | grep nvme0n1p1
Beispiel: UUID="neue-uuid-hier"
Backup
cp /etc/fstab /etc/fstab.backup
fstab editieren
nano /etc/fstab
ÄNDERN:
ALT: UUID=0bcdb676-123c-4658-925e-9cba9ecf45df / ext4 ...
NEU: UUID=NEUE-UUID-HIER / ext4 ...
Syntax prüfen
mount -a
Sollte keine Fehler zeigen (Warnungen OK)
GRUB neu installieren:
grub-install /dev/nvme0n1
Sollte zeigen:
Installing for x86_64-efi platform.
Installation finished. No error reported.
update-grub
Sollte Kernel finden und grub.cfg generieren
Initramfs neu bauen:
update-initramfs -u -k all
4.3 Netzwerk anpassen
Interface-Namen prüfen
ip link show
/etc/network/interfaces editieren
nano /etc/network/interfaces
Falls Interface-Name anders (meist enp0s31f6 statt eth0):
allow-hotplug enp0s31f6
iface enp0s31f6 inet dhcp
4.4 Chroot verlassen und unmounten
exit
Unmount in UMGEKEHRTER Reihenfolge!
umount /mnt/new-system/dev/pts umount /mnt/new-system/run umount /mnt/new-system/sys umount /mnt/new-system/proc umount /mnt/new-system/dev umount /mnt/new-system umount /mnt/backup
reboot
Phase 5: Post-Recovery (30 Minuten)
5.1 Erster Boot
Nach dem Boot als root einloggen:
Netzwerk prüfen
ip a ping -c 3 8.8.8.8
Falls kein Netzwerk:
systemctl restart networking
SSH aktivieren
systemctl start ssh systemctl enable ssh
5.2 RAID-Arrays wiederherstellen
WICHTIG: Arrays sind LUKS-verschlüsselt!
Arrays assemblieren:
mdadm --assemble --scan
Status prüfen:
cat /proc/mdstat
Sollte md125 und md126 zeigen
LUKS entsperren (Passwort erforderlich!):
cryptsetup luksOpen /dev/md125 cr_md125 cryptsetup luksOpen /dev/md126 cr_md126
Mounten:
mount /dev/mapper/cr_md125 /data mount /dev/mapper/cr_md126 /data2
Prüfen:
df -h | grep data
Für automatisches Entsperren beim Boot:
/etc/crypttab prüfen/anpassen!
5.3 Docker-Services starten
systemctl status docker
Falls nicht läuft:
systemctl start docker
Container-Status
docker ps -a
Alle Container starten
docker start $(docker ps -aq)
Warten (2-3 Minuten)
docker ps
5.4 Kritische Services prüfen
Apache
systemctl status apache2 curl -k https://localhost/site
Backup-Timer
systemctl status nvme-backup.timer systemctl list-timers | grep backup
Emby
systemctl status emby-server
Alle fehlgeschlagenen Services anzeigen
systemctl list-units --failed
Phase 6: Vollständige Verifikation
6.1 Service-Checkliste
Zu prüfende Services:
6.2 Docker-Container prüfen
Alle Container sollten "Up" sein
docker ps --format "table {{.Names}}\t{{.Status}}"
Logs bei Problemen prüfen
docker logs <container-name>
6.3 RAID-Integrität
RAID-Status detailliert
mdadm --detail /dev/md125 mdadm --detail /dev/md126
Smart-Status der RAID-Disks
smartctl -a /dev/sda | grep -E "SMART overall|Reallocated"
Troubleshooting
Problem: GRUB Error "no such device"
- Von Live-USB booten
- Chroot-Prozedur wiederholen
- UUID in /etc/fstab nochmals prüfen
- update-grub erneut ausführen
Problem: Netzwerk funktioniert nicht
ip link show
Interface-Name notieren (z.B. enp0s31f6)
nano /etc/network/interfaces
Interface-Namen anpassen
systemctl restart networking
Problem: RAID-Arrays werden nicht entschlüsselt
Prüfen ob Arrays da sind
cat /proc/mdstat
Manuell entsperren
cryptsetup luksOpen /dev/md125 cr_md125 cryptsetup luksOpen /dev/md126 cr_md126
/etc/crypttab prüfen
cat /etc/crypttab
Sollte beide Arrays enthalten
Problem: Docker-Container starten nicht
systemctl restart docker docker start <container-name> docker logs <container-name>
Zeitplan
Kritische Hinweise
RAID-Verschlüsselung: Die RAID-Arrays md125 und md126 sind mit LUKS verschlüsselt! Das Entschlüsselungs-Passwort wird benötigt. Ohne dieses Passwort sind die 113TB Daten nicht zugänglich.
Interface-Namen: Das Netzwerk-Interface heißt enp0s31f6, NICHT eth0. Dies muss in /etc/network/interfaces angepasst werden.
Docker-Volumes: Alle im Backup enthalten unter /var/lib/docker/volumes/
Backup-HDD: Device /dev/sdar1 mit Label NVME_BACKUP - NIEMALS formatieren!
IP-Adressen: Bei MAC-Änderung könnte DHCP neue IP vergeben.
Notfall-Kontakte
- Zugriff via Live-System immer möglich
- Backup-HDD (/dev/sdar1) ist die Lebensversicherung
- RAID-LUKS-Passwort sicher aufbewahrt?
- Logs in /var/log/ und /root/chatgpt-logs/
Nach erfolgreicher Recovery
Backup-System prüfen:
Backup-Timer prüfen
systemctl status nvme-backup.timer systemctl list-timers | grep nvme
Test-Backup
systemctl start nvme-backup.service
Log beobachten
tail -f /mnt/nvme_backup/_logs/run-*.log
HDD als NTFS unter Linux richtig formatieren
Szenario: Raid-Platte geht noch, liefert aber sporadische Fehler in dmesg z.B. -> wird im Raid ersetzt -> ist dann "über" -> kann als Serien-Sammelplatte noch verwendet werden
Damit die Platte auch unter Windows richtig erkannt wird ist folgendes zu beachten:
Partitionstyp muss auf 0x07 (HPFS/NTFS/exFAT) stehen!
Partitionieren mit gdisk
sudo gdisk /dev/sdX
- erst alte Linux Raid Partiton löschen: d -> 1 -> w
n→ Neue Partition anlegen (Eingaben bestätigen oder (falls gewünscht) Start- und Endsektor anpassen)0700als Typ für NTFS setzen (wird ggf. vorgeschlagen, sonst nachfragen)w→ Schreiben und gdisk verlassen
Formatieren mit mkfs.ntfs
sudo mkfs.ntfs -f /dev/sdX1
Mounten mit
sudo mkdir -p /mnt/ntfs sudo mount -t ntfs-3g /dev/sdX1 /mnt/ntfs
Booten überhaupt !!!
Bios 12 ist OK. Kerne laufen beide auf 2.5Ghz.
Beide Karten sind OK und müssen auch beim Booten drin sein
Wenn die Laufwerke vom 4-Ch Sata-Controller ab sind, wir auch gebootet.
Dann können sie Hot-Geplugged werden -> geht :-)
Jetzt testen dass auch alle 27 (!) Laufwerke da sind.
/root/bin/diskserial_sort.sh
Dann weiter wie im Raidabschnitt beschrieben
mdadm --assemble --scan
Raid-Karten Kernel-Treiber nach Kernelupdate
cd /Nach_Kernelupdate/rr2340-linux-src-v1.7/product/rr2340/linux/
make clean make make install
Manuelles starten (nach Reboot automatisch)
modprobe rr2340
Grub und Root-Festplatte
in /boot/grub/menu.lst z.B.
kernel /boot/vmlinuz-2.6.31.14-0.6-desktop root=UUID=d06e4d6a-44d7-4f09-9ea3-a4cb8f120770 ...
UUID einer Festplatte herausfinden
blkid /dev/sdq8
Screen-Umgebung
Liste aller Screens
screen -ls
Starten
screen -S NAME
Detach
Strg-a d = detach
Reatach
screen -r NAME
ODER Wieder reingehen
screen -x NAME
Screens beenden
im Screen Strg-a k (wie kill)
Arch Linux AUR Pakete
- tarball herunterladen - nach /builds entpacken (tar -xzf xxxx.tar.gz) - dort makepkg - pacman -U xxxx.pkg.tar.xz
RAR unter Linux
RAR-Archiv testen
rar t xxxxx.rar
Wake-On-Lan
Netzwerkkarte in System->Gerätemanager erlauben und Magic Paket einstellen im Bios PCI aufwecken erlauben Mac-Adresse und Netzwerk-IP wissen
Uni
Linux-Konsolen-Befehl zum Aufwecken auf Uni-Rechner Big-Blue2 aus "Hibernate":
wol -i 132.187.33.255 90:e6:ba:43:c2:dc
Busfahrer an Uni:
wol -i 132.187.33.255 b8:ac:6f:67:e6:43
Brücknerstrasse
Aufwecken aus "Standby"
(Bachus)
wol -i 255.255.255.255 00:1e:8c:46:10:8c
(Myth intern)
wol -i 255.255.255.255 00:14:85:e8:10:4c
Myth PCIe
wol -i 255.255.255.255 00:e0:45:49:00:09
Tool um Windows um Remote-Verbindung schlafen zu legen PowerOff z.B. bei
http://www.chip.de/downloads/Poweroff_21571048.html
Linuxbefehl für OpenSuse um per Konsole zu suspenden:
pm-suspend
-> Vorsicht: Festplatten verhalten sich komisch
"HDIO_DRIVE_CMD(identify) failed: Invalid exchange"
bei
/root/bin/diskserial_sort.sh
Aufwecken über Fritzbox direkt problemlos möglich.
Remote-Desktop
Big-Blue: SSH auf wolf.physik.uni-wuerzburg.de mit Tunnel: 33889 auf Ziel 132.187.33.133:3389 Dann localhost:33889
Myth: dergagi.dyndns.org normal (ohne Angabe gilt Port 3389)
Bachus: dergagi.dyndns.org:33890
Ordnergröße in Konsole anzeigen
du -sh /home
Für Platzstatus auf Partitionen
df -h
DU-Meter für SuSE/Linux
KTrafficAnalyzer, z.B. über 1-Klick Installation bei http://software.opensuse.org/search
NTM http://netramon.sourceforge.net/eng/index.html
Bandwidth-Monitor für Console, z.B. auch Ubuntu
bwm-ng
bmon
Netzwerk-Geschwindkeit testen
Tool: iperf gibts für Linux, Windows, Mac Server (empfängt Testdaten)
iperf -s
Client (sendet Daten)
iperf -c 192.168.1.60 (Myth) ipfer -c 192.168.1.66 (Store)
Manuel RPM Pakete installieren
rpm -ihv nedit-5.5-31.8.x86_64.rpm
Locate auf Data/Data2
locate -i -d /data/locatedb "mein suchbegriff"
USB-Device mounten
mount -t ntfs-3g /dev/sdj5 /usb -o force
NTFS Linux
mount -t ntfs-3g /dev/sds1 /mo1
Opensuse: IP über DHCP erneuern
1. Open a terminal and su - to root. 2. Type ifconfig to show the current IP address that you received from DHCP. 3. Type dhcpcd -k to send the appropriate signals to dhcpcd. 4. Now bring the interface back up by typing ifup eth0. 5. Type ifconfig to show the new IP address.
System-Backup-Image von USB-Platte mounten
mount -o loop /media/Data5/store_root.img /mnt/loop/
Verzeichnisse synchronisieren
mit grsync
Devices neu einlesen im laufenden Betrieb ohne Reboot
blockdev --rereadpt /dev/sdx
Laufwerke am RocketRaid neu einlesen im laufenden Betrieb ohne Reboot
Kernelmodul da?
lsmod rr2340
Kernelmodul entfernen/löschen
rmmod rr2340
Kernelmodul wieder laden/starten
modprobe rr2340
KDE Remote Desktop
krdc -> Client
TightVNC -> Client
krfb -> Server (über Konsole z.B. mit Xming starten, wegen Grafik)
Port Forwarding im Router: Kontrolle unter: vi home/root/kde4/share/config/krfbrc
JDownloader
Installieren über Script von Homepage
1. wget must be installed on system! 2. Download jd.sh http://212.117.163.148/jd.sh 3. chmod +x jd.sh 4. start jd.sh -> ./jd.sh
Note: Open jd.sh to read Manual or change Settings!
Starten nach Installation:
java -jar /home/gagi/.jd/JDownloader.jar
One-Click Install auf Konsole
OCICLI <YMP URL>
Cronjobs
Liste
crontab -l
Einträge ändern
crontab -e
dort dann im vi editieren
Data Scrubbing, automatische Suche einmal im Monat nach BadBlocks
In short: Especially if you run a RAID5 array, trigger an active bad block check on a regular basis, or there is a high chance of hidden bad blocks making your RAID unusable during reconstruction.
Normally, RAID passively detects bad blocks. If a read error occurs, the data is reconstructed from the rest of the array, and the bad block is rewritten. If the block can not be rewritten, the defective disk is kicked out of the active array.
Once the defective drive is replaced, reconstruction will cause all blocks of the remaining drives to be read. If this process runs across a previously undetected bad block on the remaining drives, another drive will be marked as failed, making RAID5 unusable. The larger the disks, the higher the odds that passive bad block detection will be inadaquate. Therefore, with today's large disks it is important to actively perform data scrubbing on your array.
With a modern (>=2.6.16) kernel, this command will initiate a data consistency and bad block check, reading all blocks, checking them for consistency, and attempting to rewrite inconsistent blocks and bad blocks.
echo check >> /sys/block/md127/md/sync_action echo check >> /sys/block/md125/md/sync_action
You can monitor the progress of the check with:
watch -n .1 cat /proc/mdstat
You should have your array checked daily or weekly by adding the appropriate command to /etc/crontab.
Steht für jeden 8. des Monats in Crontab.
If you find yourself needlessly checking your array (like I was) and want to stop it safely, you can either stop the entire array, or:
echo idle >> /sys/block/md127/md/sync_action echo idle >> /sys/block/md125/md/sync_action
TigerVNC
Start Server
vncserver :1 vncserver :2
Kill Server
vncserver -kill :1
Port 5901
dergagi.selfhost.bz:5901 dergagi.selfhost.bz:5902
Auflösung ändern:
im VNC-Fenster (also schon remote)
xrandr -s 1920x1200
XTerm Benutzer wechseln:
su gagi
Autostart
in /etc/rc.local
su gagi -c "vncserver -geometry 1920x1080 -alwaysshared -localhost -dpi 96 :1"
RSYNC volles Systembackup
rsync -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/data","/data2","/suse","/rsync-backup"} / /rsync-backup/