JoschaMiddendorf / fhem-docker

Docker Container for FHEM House-Automation-System - Full install with all dependencies
MIT License
6 stars 0 forks source link

Erweiterung des Ansatzes auf mehrere fhem-Container #27

Closed hartenthaler closed 6 years ago

hartenthaler commented 6 years ago

Hallo Joscha! Erst einmal: deine Docker-Anwendung ist super und hat auf Anhieb funktioniert! Ich möchte mit fhem von von meiner lange gewachsenen RasperryPi-Lösung auf einen Intel NUC (mit docker) umziehen. Gestern habe ich den NUC aufgesetzt und docker und docker-compose sowie Portainer installiert. Ich habe mir ein Repository bei Bitbucket angelegt und das lokale Verzeichnis per git damit verknüpft (zur Datensicherung). Dann habe ich Dein fhem-docker geladen (tolle Funktion dass dabei das leere Verzeichnis automatisch gefüllt wird). Dein Healthcheck ist ebenfalls super. Soweit alles gut, aber die Realität ist natürlich komplexer, da ich hier sehr viele Komponenten am laufen habe. Also habe ich heute alternativ die fhem-docker-Container von https://github.com/klein0r/fhem-docker geladen. Geht schon in die richtige Richtung, aber Dein Dockerfile ist sauberer und gefällt mir besser. Konkret:

  1. Hast Du Interesse Deinen Ansatz auf einen Ansatz mit mehreren Containern zu erweitern?
  2. das .gitignore bei Matthias Kleine ist gut und fehlt bei Dir
  3. Ich habe einen fhem-Chatbot auf Basis RiveScript und Telegram und den würde ich gerne in einen weiteren Container packen. Wie kommuniziert der Prozess in diesem Chatbot-Container dann mit dem fhem-Hauptprozess? fhem-to-fhem?
  4. Ich möchte auch Sonos gerne in einen Container packen. Dazu gibt es im fhem-Forum einen eigenen thread.
  5. Ich möchte von den Logfiles auf die Datenbank umsteigen. Und diese dann einmal in der Nacht per DBRep auf ein NAS sichern.
  6. Ich brauche noch ein paar Pakete wie Nmap::Parser, Image::Grab oder LWP::Simple (letzteres nur im Chatbot-Container) sowie ein paar weitere fhem-Module, die nicht im Standard sind (TALKTOME, TALKTOUSER, TEERKO, LaMetric, ...). Kein Problem, aber was ist der richtige Ansatz? Kopiert man diese Module einfach von Hand nach fhem/core/FHEM oder hinterlegt man solche Kopiervorgänge sauber dokumentiert im passenden Dockerfile eines Containers (z.B. werden die TALKTOxx nur im Container meines Chatbots benötigt)?
  7. In der fhem.cfg habe ich nur die Basisdinge festgelegt. Für jedes Thema gibt es dann eine include-Datei, etwa homematic.cfg. Sinnigerweise würde ein homematic-Container seine eigene include-Datei mitbringen, die nur geladen wird, wenn der Container aktiv ist. Wie man das hinbekommt, ist mir aber noch nicht klar. Also wenn ich keinen Sonos-Container habe, dann habe ich auch kein Sonos-fhem-Device. Wenn der Container aber aktiv ist, dann ist natürlich auch das das Sonos-Device Bestandteil der fhem-Konfiguration.
  8. Der Zugang von außen soll über Reverse Proxy oder VPN sicherer werden.
  9. Einige fhem-Module haben Bedarf für API-Key oder Passwort. Erster Punkt wo es mir auffiel war der Zugang zur Fritzbox. Solche Sachen gehören aus meiner Sicht irgendwie zentral gesammelt, damit man sie vernünftig pflegen kann. Was ist die richtige Strategie?
  10. Um die Sicherheit zu erhöhen, würde ich gerne die inflationären Portfreigaben etwas reduzieren, mich also mit den docker-Netzen vertraut machen.
  11. Als Fernziel sehe ich: man lädt ein kleines Programm, das das lokale Netz durchsucht. Wenn es Sonos und Philips Hue findet, dann wird ein passendes docker-compose.yml dynamisch erzeugt. Der Nutzer kann noch anklicken welche Module er noch zusätzlich haben will, etwa Wetter oder Verkehr und schwupsdiwups hat er ein lauffähiges fhem, das er dann noch von Hand beliebig optimieren kann. Hast Du Interesse mich auf diesem Weg zu begleiten? Ich werde wohl in der nächsten Zeit rund 20 Stunden pro Woche reinstecken, damit mein System auf NUC mit docker besser wartbar wird als bisher. Hast Du finanzielle Vorstellungen?
JoschaMiddendorf commented 6 years ago

Hallo Hermann, vielen dank erstmal für dein positives feedback. Ich werde mal versuchen so gut es geht auf deine Fragen ein zu gehen.

  1. Mein Ansatz ist es verschiedene Dienste nicht in einem Container zusammen zu fassen sondern diese, getrost nach dem Motto ein Dienst ein Server, in verschiedenen Containern voneinander getrennt zu halten. Die Erweiterung kann dann geschehen indem man die Container installiert die man benötigt um seine Infrastruktur auf zu bauen. Wenn es dann keinen Container gibt der eine adäquate Lösung für das problem dar stellt spricht nichts dagegen auch selber hand an zu legen.

  2. .gitignore ist dafür da um zu verhindern das gewisse Dateien in die repository gepusht werden die für die Software nicht benötigt werden. Das ist bei mir nicht notwendig da in meiner repository ausschließlich Daten und Verzeichnisse liegen die für den build auch benötigt werden. Matthias braucht das soweit ich weis. Da er das gesamte fhem Verzeichnis in seiner repository liegen hat. Inklusive logs und so weiter diese sollen dann natürlich nicht immer mit gepusht werden.

  3. Optimal währe es wenn die Kommunikation über Netzwerk stattfindet und der Chatbot container dann für fhem über eine entsprechende API erreichbar ist.

  4. Hier verstehe ich deine konkrete Frage nicht ganz...

  5. das ist ohne weiteres möglich ich nutze hierfür den container von Linuxserver.io linuxserver/mariadb Zur installation und Konfiguration hat Matthias auch sehr gute videos gemacht. https://haus-automatisierung.com/hardware/fhem/2016/05/20/fhem-tutorial-reihe-part-7-mysql-server-fuer-logging-nutzen.html https://haus-automatisierung.com/hardware/fhem/2018/03/12/fhem-tutorial-reihe-part-7-3-mysql-mariadb-server-fuer-logging-nutzen.html https://haus-automatisierung.com/hardware/fhem/2017/11/27/fhem-tutorial-reihe-part-46-dbrep.html

  6. Zusätzliche fhem module kannst du tatsächlich einfach in das /opt/fhem/FHEM/ Verzeichnis legen diese sind dann nach einem "shutdown restart" in FHEM verfügbar. wenn diese automatisch upgedatet werden sollen kannst du die entsprechende repository auch in der /opt/fhem/FHEM/controls.txt hinterlegen sollte diese dann dafür ausgelegt sein wie z.B. https://github.com/klein0r/fhem-tasmota. Wenn du zusätzliche Pakete benötigt nehme ich diese gerne in meinen Container mit auf, bitte lass mir doch dann nochmal Links zu der entsprechenden Dokumentation (commandref oder Beschreibung des Moduls) zukommen damit ich prüfen und dokumentieren kann was genau benötigt wird. Ich installiere das dann schnellstmöglich nach.

  7. das währe machbar indem du die Dateien einzeln in den fhem container maps. ich halte das aber nicht für sinnig da: a) FHEM seine configuration dann auch bei jeder Änderung neu einlesen müsste und hierfür jedesmal ein Neustart oder ein rereadcfg notwendig währe. das reduziert die uptime und ist alles andere als das was wir wollen. b) Wenn ich einen sonos Container habe oder dauerhaft am laufen habe brauche ich in FHEM dafür auch keine configuration Einen server dient immer wieder an und ab zu schalten ist in der Regel nicht das ziel. entweder benötigt man den dienst dann legt man ihn an und lässt ihn laufen oder man benötigt ihn nicht, dann legt man ihn nicht an und man benötig in FHEM dafür auch keine config.

  8. Kluge Entscheidung! Hier kann ich dir diesen NGINX reverse proxy empfehlen er hat den Zertifikats generierungs kram von LetsEncrypt direkt schon mit dabei linuxserver/letsencrypt solltest du dich für den container entscheiden geb mir bescheid dann kann ich gerne noch tips zur configuration geben.

  9. Bei mir sammelt sich das ganze nicht wirklich das sind halt so die schwächen an FHEM jeder der ein Modul entwickelt kocht da sein eigenes Süppchen und am ende liegen die Daten da wo der Entwickler es mal als sinnvoll erachtet hat. also richte die da dann am besten nach der entsprechenden doku in der commandref. Meistens landen die Daten dann in der fhem.cfg so wie alle Definitionen und attribute.

  10. klar kannst du deine container auch intern vernetzen da meine container allerdings jeweils wie eigenständige Server im Netzwerk hängen und auch so miteinander kommunizieren kann ich die damit nicht wirklich helfen ich habe erstmal ein par Ports auf gemacht damit niemand in Bedrängnis kommt aber du musst diese ja nicht weiter leiten. offen sind diese nur wenn du sie über "docker run -d --name fhem-docker -p :" auch frei gibst.

  11. Das klingt auf jeden fall interessant aber auch nach einer Herausforderung. Mit docker-compose.yml kenne ich nicht nicht aus da mein system komplett auf UnRaid läuft und das Betriebssystem einen eigenen dienst hat Docker Container zu verwalten. Dein Projekt klingt auf jeden fall interessant, aber da ich mit software (noch) nicht mein geld verdiene sondern noch am studieren bin ind nebenher noch arbeite sind 20 stunden in der Woche leider grade nicht übrig. Es seihe denn du hast dahin gehend eine stelle zu vergeben... ;-)

Konkrete finanzielle Vorstellungen habe ich bisher nicht, aber für den fleißigen Studenten kommt jede Unterstützung zur Erweiterung des Heimautomatisierungshorizonts gelegen. Dafür der Knopf ;-) paypal

hartenthaler commented 6 years ago

Ok, Schritt für Schritt. Der Knopf war als erstes dran ;-)

  1. .gitignore: Ich habe mit einem leeren lokalen Verzeichnis gestartet. Dann: docker run -d --name fhem-docker -v /home/hermann/docker/fhem-docker/fhem/core:/opt/fhem -p 7072:7072 -p 8083:8083 diggewuff/fhem-docker Damit liegen in meinem lokalen Verzeichnis auch die fhem-Verzeichnisse wie backup etc. Wenn ich dann mein lokales Verzeichnis per: git add fhem; git commit -m 'initial' -a; git push im privaten Repository auf Bitbucket sichere, dann werden auch unnötige Dinge wie das backup-Verzeichnis dorthin gesichert. Daher ist aus meiner Sicht ein .gitignore im Verzeichnis fhem-docker sinnvoll. Dort ist bei mir nun drin: /fhem/core/FHEM/FhemUtils/uniqueID /fhem/core/backup/ /fhem/core/cache/ /fhem/core/restoreDir/* Somit ist mein Repository auf Bitbucket frei unnötigen Inhalten. Mein Vorschlag wäre, dass Du das bei Dir auch aufnimmst, wenn da nicht etwas dagegen spricht.

  2. Sonos: Falls Du überhaupt Sonos-Lautsprecher hast! Das fhem-Sonos-Modul startet spezielle Sonos-Dienste. Die sind manchmal hakelig und es macht durchaus Sinn diese in einen eigenen Container auszulagern. In https://forum.fhem.de/index.php?topic=71191.0 ist einiges beschrieben, aber da ich mich erst seit drei Tagen mit docker beschäftige, ist mir noch nicht alles klar. Blickst Du hier durch?

  3. Der nächste Container ist NGINX. Ich finde den Ansatz von https://techblog.sitegeist.de/docker-compose-setup-mit-nginx-reverse-proxy/ sehr spannend, da ich neben fhem sicher auch auf andere Dienste in meiner docker-Umgebung zugreifen möchte. Wie hast Du deinen NGINX-Container konfiguriert?

Danke schon einmal für Deine sehr ausführlichen Antworten! Ggf. auch weiter per e-mail (hermann@hartenthaler.de).

JoschaMiddendorf commented 6 years ago

Hallo Hermann, zuerst einmal vielen dank für deine großzugige finanzielle Unterstützung, ich wes das sehr zu schätzen. Ich bleibe erstmal noch hier dammit andere mit ähnlichen Ansätzen auch davon profitieren können.

Zum Thema .gitignore in diesem file lassen sich Pfade und Dateien angeben die bei einem push (upload) in eine repository nich mit hochgeladen (ignoriert) werden sollen. Da du BitBucket als datensicherungsziel für dein backup nutz kannst du natürlich gerne dein eigenes .gitignore file anlegen um die Sicherung (den upload) gewisser Daten zu verhindern. Das kann sogar sinnvoll sein. In meiner repository ist das allerdings konkret deshalb nicht notwendig weil niemand weder do noch ich eine laufende installation in das repository hochladen wird, im Gegenteil in meiner repository liegen garkeine Daten die etwas mit FHEM zu tun haben es ist lediglich im DOCKERFILE hinterlegt das FHEM und alle zugehörigen Daten bei dem build des containers frisch von den FHEM Servern herunter geladen werden sollen. im Umkehrschluss da in der git repository keine Daten liegen, weder auf git noch bei mir lokal gibt es keinen bedarf den upload dieser Daten auch zu verhindern. Aber wie gesagt, wenn es deine persönliche Backupstrategie ist, deine gesamte Installation, sprich das /opt/fhem/ Verzeichnis, in eine private repository zu pushen kann ein persönliches .gitignore auch sinn machen aber dann solltest du dieses für dich personalisiert auch selber hinterlegen. In meiner repository hätte ein .gitignore mit den eintragen /fhem/core/FHEM/FhemUtils/uniqueID /fhem/core/backup/ /fhem/core/cache/ /fhem/core/restoreDir/* garkeine Funktion da diese Verzeichnisse in meiner repository garnicht existieren. PS: Bei Matthias liegt das gesamte /opt/fhem/ verzins in seiner repo. daher braucht er auch das .gitignore.

Sonos: Vorweg, ich besitze keine Sonos Gerate, aber ich habe trotzdem mal einen schnellen blick in den thread geworfen. Wie ich da lese müsste man da mal ein bisschen mit Multicast rumtesten das ist ohne hardware allerdings ein bisschen schwierig, es gibt dort aber schon Ansätze an denen du dich ja mal lang hangeln kannst. Ich empfehle immer, so viele Container wie möglich in bridged networks laufen zu lassen weil diese dann einfach Netzwerktechnisch voneinander abgeschottet sind. Problem ist nur das das leider dem betrieb von Multicast widerspricht denn das beruht darauf das die Geräte sich gegenseitig im Netzwerk sehen können. Noch ein kleiner Schuss ins blaue: Versuche doch mal auf deinem Router nach einer Einstellung wie "Enable Multicast DNS" zu suchen. Ein Multicast DNS Dienst macht nämlich genau das, Multicast Trafic Netzwerk übergreifend transportieren. Hat bei mir geholfen um Homebridge VLAN übergreifend nutzen zu können.

NGINX: Der Ansatz ist tatsächlich klasse. Da mein Host OS (UnRaid) allerdings nicht mit Docker Compose arbeitet, sondern wie schon gesagt mit einer eigenen Management Utility, für mich allerdings nicht umsetzbar. Ich konfiguriere meinen NXINX komplett zu fuß in den entsprechenden config files, und dann für jeden dienst den ich dann ins netz stellen möchte eine subdomain. (eine feste IP und ne eigene Domain sind dann schon was feines, geht aber auch mit dynDNS) ein configfile für einen NGINX dienst sieht dann in etwa so aus:

server {
    listen 443 ssl http2;
        server_name fhem.meinedomain.de;

    ssl_certificate /config/keys/letsencrypt/fullchain.pem;
    ssl_certificate_key /config/keys/letsencrypt/privkey.pem;
    ssl_dhparam /config/nginx/dhparams.pem;
    ssl_ciphers 'XXXXXXXXXXXXXXXXXXXXXX';
    ssl_prefer_server_ciphers on;

        client_max_body_size 0;

    location / {
        include /config/nginx/proxy.conf;
        proxy_pass http://LokaleIPdesContainers:8083;   
            proxy_buffering off;
                proxy_max_temp_file_size 0;
    }
}

PSS: Fehlen dir denn jetzt noch Perl Module? Wenn Ja, dann sag mir doch nochmal konkret welche und wofür diese benötigt werden.

hartenthaler commented 6 years ago

Ich scheine noch ein grundsätzliches Verständnisproblem zu haben. Du schreibst

in meiner repository liegen gar keine Daten die etwas mit FHEM zu tun haben es ist lediglich im DOCKERFILE hinterlegt das FHEM und alle zugehörigen Daten bei dem build des containers frisch von den FHEM Servern herunter geladen werden sollen

So sehe ich das im Idealfall auch. Also es gibt ein DOCKERFILE und da steht alles drin was nötig ist um einen lauffähigen fhem-Container zu erzeugen. Nun aber zur Realität: Ich füge neue Komponenten zu meiner Heimautomation dazu. fhem erzeugt ggf. per autocreate die zugehörigen fhem-Devices. Oder ich erzeuge und konfiguriere die passenden Devices über die fhem-Kommandooberfläche, also ändert sich fhem.cfg. Wie aber nun gelangen diese Informationen bei Dir ins DOCKERFILE? Oder man konfiguriert einen Floorplan oder die TabletUI-Oberfkäche oder gestaltet einen Plot? Wie machst Du diese Dateiein persistent? Ich finde den Ansatz das gesamte Verzeichnis /opt/fhem/ persistent zu machen pragmatisch. Allerdings muss man dann dieses Verzeichnis irgendwo hin sichern, damit man es wieder einspielen kann, wenn man fhem neu aufsetzen möchte. Damit verliert aber natürlich das DOCKERFILE an Bedeutung und stellt "nur" die Grundkonfiguration von fhem her. Habe ich etwas übersehen? Wie machst Du das genau? Daran anschließend passenderweise zu Punkt 9: wo liegen Passwörter, API-Keys, Zertifikate oder ähnliche Konfigurationsdaten? Ein erster Ansatz wäre: man sammelt das alles sehr ordentlich an einer Stelle und beim Bau des fhem-Dockercontainers werden die entsprechenden fhem-Devices mit der von ihnen benötigen Information versorgt. Zweiter Ansatz, den Du anscheinend gewählt hast: man konfiguriert das fhem-Device einmalig von Hand. Pragmatisch, da die verschiedenen fhem-Devices verschiedenes verlangen. Aber dann muss man das File sichern in dem diese Informationen verschlüsselt abgelegt sind, damit man bei einem Neustart von fhem-docker nicht alles wieder erneut von Hand konfigurieren muss. Oder?

JoschaMiddendorf commented 6 years ago

Ein Dockerfile ist tatsächlich nichts anderes als eine Bauanleitung für die Grundinstallation. Die Konfiguration ist Persistent weil sie sich komplett im Verzeichnis /opt/fhem befindet und dieses sich als Volume außerhalb des Containers befindet. Backups lassen sich dann wie man möchte von /opt/fhem erstellen. Ich sichere dafür täglich alles versioniert Inkremental auf einer 2. Festplatte, und diese backup dann wöchentlich verschlüsselt übers netz auf dem Server eines Freundes 20 km entfernt. Du machst das über git, das ist auch ein weg.

Kleiner Hinweis du baust hier keinen container sondern lädst einen fertig gebauten herunter. Das ist bei Matthias auch anders, er stellt keinen fertig gebauten container zur verfügung, deshalb braucht auch jeder den gesamten Inhalt seiner git repo um den container selber zu bauen. Mein build findet automatisiert auf DockerCloud statt. Du lädst den container dann nur von dockerhub herunter und startest ihn. beim ersten mal wird dein /opt/fhem mit der basis config gefüllt und dann nie wieder von meinem Container verändert oder irgendwo hochgeladen.