Intel NUC - Der Umstieg und mein neues System unter Docker
Jetzt habe ich meinen Intel NUC schon seit mehreren Wochen hier stehen, und habe den Umzug immer vor mir her geschoben. Das lag daran, dass ich nicht einfach nur umziehen wollte, sondern auch auf Docker umsteigen. Das heißt, FHEM läuft jetzt nicht mehr direkt auf dem NUC, sondern in einem Container. Neben diesem Container habe ich noch weitere erstellt, welche dann Homebridge, Alexa, mySQL und auch einen Reverse Proxy enthalten.
In diesem kleinen Video möchte ich Euch einen schnellen Überblick über Docker geben, und wo die Stärke des Systems liegen.
Was wird benötigt?
- Etwas Know-How mit Docker
- Hardware mit etwas mehr Performance (kein Rasperry Pi)
- Ein System, auf welchem Linux mit Docker bereits installiert ist
Video
Disclaimer: Dies ist kein Einsteiger-Video. Ich gehe nicht auf jede Zeile einzeln ein und das hier gezeigte Video soll nur einen Überblick über die Möglichkeiten mit Docker aufzeigen. Möchte man tiefer einsteigen, würde ich als erstes einen Online-Kurs über Docker empfehlen, um die Arbeitsweise zu verstehen. Docker-Container sind keine Virtuellen Maschinen und können so auch nicht behandelt werden! Man spricht von “containerization” und nicht von “virtualization”. Es ist also ein komplett anderer Ansatz als zum Beispiel ESXi!
Hardware
Hier findest Du meine Hardware-Empfehlung für einen Intel NUC. Diese Konfiguration habe ich selber im Einsatz und ist von der Performance mehr als Ausreichend. Als Grund für den Wechsel vom Raspberry Pi war bei mir die auf Dauer fehlende Performance, je mehr Dienste im Einsatz waren.
Insgesamt muss man hier mit Ausgaben um die 400 Euro rechnen - im Vergleich zum Raspberry Pi ist das natürlich eine Menge, aber dafür muss man so schnell auch keine weiteren Investitionen tätigen.
Ausgangssituation
Was mich bisher gestört hat:
- Man hat einen undefinierbaren Stand des Systems geschaffen (ich wusste nicht mehr, wo genau was warum liegt)
- Alle Dienste lagen im gleichen System und waren nicht sauber getrennt
- Es wurde immer mehr dazu installiert = Chaos
- Sicherheits-Risiko: Sollte es jemand schaffen, über einen der Ports auf meinen Raspberry zu kommen, hat er die vollen Rechte.
- Ein Backup des gesamten Systems war schwierig
- Eine Testumgebung aus dem Live-System zu kopieren war sehr schwer
- Mehrere FHEM-Instanzen auf der gleichen Hardware hat nicht funktioniert
All diese Probleme habe ich mit meiner Docker-Umgebung gelöst! Ich könnte jetzt z.B. Homebridge aus meinem Setup entfernen, ohne dass auch nur ein kleiner Rückstand davon übrig bleibt. Das Host-System ist komplett sauber und enthält am Ende nur noch das Betriebssystem und die Docker-Umgebung.
Am Ende habe ich mehrere Container im Betrieb:
- FHEM
- mySQL
- HomeBridge
- Alexa
- Apache (ReverseProxy)
Die Konfigurationen der einzelnen Systeme habe ich mir von meinem Raspberry Pi zusammenkopiert und in ein sauberes git-Repository gelegt. Hier liegen jetzt nur noch Daten, welche absolut Sinn machen und alles hat seine Daseinsberechtigung. Es gibt also keinen Datenmüll mehr!
All diese Container kann ich komfortabel über die Portainer-Oberfläche verwalten.
Voraussetzungen und Probleme
Docker-Container führen Aufgaben aus, ist diese Aufgabe zu Ende, beendet sich der Container wieder. Das alles in wenigen Millisekunden und es muss kein komplettes Betriebssystem gebootet werden. Daher muss dafür gesorgt werden, dass ständig ein Prozess im Hintergrund läuft, welcher den Container für Dienste wie Apache, mySQL oder eben auch FHEM am leben hält.
Daher konnte ich nicht das normale FHEM init-Script verwenden, sondern musste einen Workaround bauen. Die Lösung hierfür ist das gobal-Attribut “nofork 1”. Dies führt dazu, dass der FHEM-Prozess nicht in den Hintergrund geschoben wird. So bleibt der Container im Status “running” und beendet sich nicht gleich wieder.
Ein weiteres Problem sind Updates. Da Container bei jedem Beenden immer wieder auf dem gleichen Stand sind wie zum Start, kann man keine Dateien persistent verändern. Führt man nun also ein “update all” aus und startet den Container neu, hat es dieses Update nie gegeben! Hier hat man nun entweder die Möglichkeit, ein Volume in den Container zu mappen, oder man muss eben die Container für ein Update immer wieder neu bauen. In meiner Live-Version wird das komplette /opt/fhem-Verzeichnis im git gehalten, sodass ich dieses dann in den Container linken kann. Das macht es an vielen Stellen sehr viel einfacher und die Update-Problematik erledigt sich dann von alleine.
Das mag am Anfang alles sehr kompliziert und nach wenig Mehrwert klingen, ist allerdings ein riesen Vorteil! Immerhin muss man sich nun bei der Art von Schreibvorgang überlegen, ob man diesen noch benötigt oder verwerfen möchte. Das heißt, dass man viel genauer wissen muss, wo welche Daten abgelegt werden (z.B. vom mySQL-Server). Außerdem kann ich mich so kurz in den FHEM-Container hängen, etwas testen, und falls es scheitert oder nicht erfolgreich ist, starte ich diesen einfach neu. Das gilt natürlich auch für zusätzliche installierte Pakete. So bleiben die Container auch sehr klein.
Durch den priveligierten Modus der FHEM-Instanz kann ich innerhalb des Containers alle USB-Geräte nutzen. Hier könnte man aber auch zur Not noch FHEM2FHEM auf einem anderen Raspberry nutzen.
Weiterhin darf FHEM nicht unter dem Benutzer “fhem” laufen, da sonst die Volumes des Host-Systems nicht beschreibbar sind. Also läuft FHEM im Container als root. Das ist aber völlig okay, da durch die Trennung der Container kein Sicherheitsrisiko entsteht. mySQL, Apache und die anderen Dienste laufen in Ihren Containern ebenfalls als root. Um dies zu bewerkstelligen, habe ich im Dockerfile einfach den fhem-Benutzer gelöscht.
Ergebnis
Aktuell habe ich genau ein Verzeichnis auf der Festplatte, welches ALLE Daten enthält. Und zwar wirklich alle. Es gibt keine einzige Datei, die zum Betrieb benötigt wird, und nicht in diesem Verzeichnis liegt. Das macht Backups sehr einfach! Wobei Backups im Prinzip eher überflüssig werden, da ich meine Konfiguration komplett im git habe. Im schlimmsten Fall gehen also nur Logs verloren. Sollte die Festplatte einmal kaputt gehen, habe ich das System also sehr schnell wieder am Laufen.
»Portainer Docker«
Offene Themen
Aktuell funktioniert alles - mit einer Ausnahme: Bluetooth. Ich habe es auf die Schnelle nicht hinbekommen, das Bluetooth-Gerät von meinem Host zu nutzen. Aber das sollte das geringste Problem sein.
Fazit
Für ein zukunfssicheres System hat sich die Arbeit auf jeden Fall gelohnt! Es ist nicht nur alles sehr viel schneller, sondern auch aufgeräumter. Durch die Aufteilung in verschiedene Container ist es sehr einfach, Funktionalitäten zu oder abzuschalten. Jetzt steht der Weiterentwicklung nichts mehr im Wege! Ich bin wirklich froh, diesen Weg gegangen zu sein (auch, wenn das alles natürlich etwas sehr technisch ist).