Mit dem neuen Raspberry Pi 3 Model B+ oder kurz RPI3B+ steht nun ein potenter Rechner zur Verfügung, der bereits in seiner Vorgängerversion Anwendung in der neuen Homematic Zentrale CCU3 findet. Somit hat er nicht nur genügend Power, um FHEM zu beherbergen, sondern auch andere Dienste wie Alexa-FHEM, Homebridge, Reverse-Proxy (NGINX) und vieles mehr.
Aber keine Angst, dieser Beitrag soll nicht zu technisch werden, sondern gezielt zeigen, wie Du in relativ kurzer Zeit Deinen RPI 3B+ mit Docker, FHEM und den Busware SCCs stabil und sicher installieren kannst.
Wer sich etwas mit Software-Entwicklung auskennt, der weiß die Vorzüge von Docker zu schätzen. Ich selbst lerne diese gerade selbst kennen und dachte, dass es ein guter Grund wäre, diesen Ansatz für die Hausautomation auszuprobieren.
Was ist Docker?
Docker bietet eine Umgebung mit der so genannte Container erstellt werden können. Diese Container beinhalten alle für das Ausführen der Anwendung erforderlichen Bestandteile wie Code, Systemtools, Bibliotheken und Einstellungen. Container isolieren quasi Software von ihrer Umgebung und stellen sicher, dass sie trotz Unterschieden, z. B. zwischen Entwicklung und Staging, einheitlich funktioniert.
Wird ein Container geschlossen, so steht er nach dem Neustart wieder in seinem ursprünglichen Zustand wieder zur Verfügung – sofern keine Maßnahmen der Speicherung der Änderungen getroffen werden.
Dabei ist zwischen zwei Dingen zu unterscheiden: docker-compose.yml und Dockerfile.
Mittels docker-compose.yml kann eine komplette Systemumgebung bestehend aus mehreren Containern, Netzwerken und persistenten Datenspeichern erstellt werden. Das Dockerfile bestimmt was in einem Container zur Verfügung steht, also das Linux-Betriebssystem, die Bibliotheken, der Anwendungscode und die Einstellungen.
Auf den ersten Blick erscheint es etwas kompliziert, aber mit ein paar grundlegenden Kenntnissen wie Pakete im Linux-Umfeld installiert werden, ist es prinzipiell sehr einfach. Darüber hinaus gibt es bereits eine Vielzahl von fertigen Docker-Containern, auf die man zugreifen kann, wie z. B. Portainer oder nginx.
Es gibt auch eine Vielzahl von FHEM-Containern, Alexa-FHEM und dergleichen, auf die Du auch zugreifen kannst. In diesem Beitrag will ich Dir aber zeigen wie einfach Du das selbst machen kannst, und wie flexibel Du die Container auf Deine Bedürfnisse anpassen kannst.
Hypriot – Eine Docker-Umgebung für den RaspberryPi (RPI)
Seit Anfang 2015 bietet Hypriot das gleichnamige Betriebssystem HypriotOS an. Ein speziell für den RaspberryPi optimiertes Betriebssystem zur Verwaltung von Docker-Containern.
Das aktuelle Image findest Du hier:
https://github.com/hypriot/image-builder-rpi/releases
Die Installation ist einfach:
- Image als ZIP laden und entpacken
- Image mit Win32 Disk Imager, ApplePiBaker oder Balea Etcher auf eine SD-Karte übertragen
- Optional kann auch noch eine Datei /boot/user-data angepasst werden, damit vor dem ersten Start von hypriot entsprechende Systemeinstellungen vorgenommen werden
Nachdem die SD-Karte vorbereitet wurde, kann der RPI gestartet werden. Hierfür am besten den RPI mit dem LAN-Kabel verbinden. So kann sichergestellt werden, dass der RPI auch erreichbar ist. WLAN-Einstellungen und sonstige Anpassungen können anschließend erfolgen.
Hinweis: Eine Installation auf einer externen mSata SSD war mit bisher nicht möglich. Ich zeige Dir im dritten Teil, wie Du die SD-Karte auf eine mSata SSD (oder sonstiges USB-Medium) übertragen kannst. Das war für mich der einfachste Weg.
Beispiel für die Datei /boot/user-data
Bitte entsprechend an Deine Bedürfnisse anpassen. Du kannst aber auch die Standard-Datei verwenden. Die weitere Beschreibung setzt diese Datei nicht voraus, sondern basiert auf dem Standard.
#cloud-config
# vim: syntax=yaml
#
# Documentation: http://cloudinit.readthedocs.io/en/0.7.9/index.html
# Set your hostname here, the manage_etc_hosts will update the hosts file entries as well
hostname: black-pearl
manage_etc_hosts: true
resize_rootfs: true
# You could modify this for your own user information
users:
- name: pirate
gecos: "Hypriot Pirate"
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video,input
plain_text_passwd: Mein-geheimes-Passwort
lock_passwd: false
ssh_pwauth: true
chpasswd: { expire: false }
# Set the locale of the system
locale: "de_DE.UTF-8"
# Set the timezone
# Value of 'timezone' must exist in /usr/share/zoneinfo
timezone: "Europe/Berlin"
# Update apt packages on first boot
package_update: true
package_upgrade: true
package_reboot_if_required: true
#package_upgrade: false
# # Install any additional apt packages you need here
# packages:
# - ntp
# WiFi connect to HotSpot
# - use `wpa_passphrase SSID PASSWORD` to encrypt the psk
write_files:
- content: |
hostname
persistent
option rapid_commit
option interface_mtu
require dhcp_server_identifier
slaac private
interface wlan0
static ip_address=192.168.1.XXX/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
path: /etc/dhcpcd.conf
- content: |
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
path: /etc/network/interfaces.d/wlan0
- content: |
country=de
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="Mein-WLAN-SSID"
psk="Mein-WLAN-Passwort"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}
path: /etc/wpa_supplicant/wpa_supplicant.conf
- content: |
hdmi_force_hotplug=1
enable_uart=1
start_x=0
disable_camera_led=1
gpu_mem=1
dtparam=audio=on
dtoverlay=pi3-miniuart-bt
path: /boot/config.txt
- content: |
dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 cgroup_enable=cpuset cgroup_enable=memory swapaccount=1 elevator=deadline fsck.repair=yes rootwait logo.nologo vt.global_cursor_default=0
path: /boot/cmdline.txt
- content: |
#!/bin/sh -e
/usr/bin/tvservice -o
sudo sh -c 'echo none > /sys/class/leds/led0/trigger'
sudo sh -c 'echo none > /sys/class/leds/led1/trigger'
sudo sh -c 'echo 0 > /sys/class/leds/led0/brightness'
sudo sh -c 'echo 0 > /sys/class/leds/led1/brightness'
exit 0
path: /etc/rc.local
# These commands will be ran once on first boot only
runcmd:
# Pickup the hostname changes
- 'systemctl restart avahi-daemon'
- 'systemctl mask serial-getty@ttyAMA0.service'
# Activate WiFi interface
- 'ifup wlan0'
# Run portainer, so we can see our logs and control stuff from a UI
- [
docker, service, create,
"--detach=false",
"--name", "portainer",
"--publish", "9000:9000",
"--mount", "type=volume,src=portainer_data,dst=/data",
"--mount", "type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock",
"portainer/portainer", "-H", "unix:///var/run/docker.sock", "--no-auth"
]
Hypriot für FHEM vorbereiten
Mit den folgenden Anpassungen richtest Du eine WLAN-Verbindung ein, setzt eine festet IP-Adresse und schaltest die LEDs des Raspberry Pi aus und deaktiviert den HDMI-Port. Letzteres spart etwas Strom.
vi /etc/dhcpcd.conf
In dieser Datei wird die statische IP-Adresse eingerichtet. In meinem Beispiel ist es das On-Board WIFI-Modul des RaspberryPi (RPI 3 B+).
hostname
clientid
persistent
option rapid_commit
option interface_mtu
require dhcp_server_identifier
slaac private
interface wlan0
# HIER DEINE ANPASSUNGEN VORNEHMEN
static ip_address=192.168.1.xxx/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
vi /etc/wpa_supplicant/wpa_supplicant.conf
In dieser Datei werden die Zugangsdaten für das WLAN gespeichert.
country=DE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="Meine-WLAN-SSID"
psk="Mein-WLAN-Passwort"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}
vi /etc/rc.local
In dieser Datei werden die LEDs des RaspberryPi ausgeschaltet.
#!/bin/sh -e
sudo /usr/bin/tvservice -o
sudo sh -c 'echo none > /sys/class/leds/led0/trigger'
sudo sh -c 'echo none > /sys/class/leds/led1/trigger'
sudo sh -c 'echo 0 > /sys/class/leds/led0/brightness'
sudo sh -c 'echo 0 > /sys/class/leds/led1/brightness'
sudo iwconfig wlan0 power off
exit 0
Spezielle Einstellungen für den Busware SCC
Wenn Du einen oder mehrere SCC der Firma Busware verwenden willst, dann musst Du noch die folgenden Einstellungen vornehmen, damit Du ihn in FHEM verwenden kannst.
vi /etc/inittab
In dieser Datei den folgenden Eintrag löschen oder wie im Beispiel auskommentieren.
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
vi /boot/config.txt
In dieser Datei werden entsprechende Einstellungen vorgenommen, so dass der Busware SCC mit FHEM verwendet werden kann. Da ich weder Monitor noch graphische Benutzungsoberfläche verwenden will, habe ich den Grafikspeicher auf 1MB herunter gesetzt.
hdmi_force_hotplug=1
enable_uart=1
start_x=0
disable_camera_led=1
gpu_mem=1
dtparam=audio=on
dtoverlay=pi3-miniuart-bt
vi /boot/cmdline.txt
Auch in dieser Datei müssen entsprechende Anpassungen vorgenommen werden, damit der Busware SCC mit FHEM und dem RaspberryPi funktioniert. Darüber hinaus habe ich noch ein paar Anpassungen gemacht, so dass Logo under dergleichen nicht mehr angezeigt werden.
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 cgroup_enable=cpuset cgroup_enable=memory swapaccount=1 elevator=deadline fsck.repair=yes rootwait logo.nologo vt.global_cursor_default=0
Zum Schluss muss noch der ttyAMA0-Dienst abgeschaltet werden:
systemctl mask serial-getty@ttyAMA0.service
Container für FHEM-Umgebung einrichten
In der Datei docker-compose.yml werden alle Container verwaltet, die wir für die FHEM-Umgebung verwenden wollen. Darüber hinaus können wir diese in Beziehung zueinander setzen, z. B. in Form von Abhängigkeiten, Netzwerkzugriffe und Datenspeicherung außerhalb der Container. Letzteres ist besonders wichtig, denn bei jedem Start werden die Container wieder auf ihren Ursprung zurückgesetzt.
Die folgenden Container habe ich in Verwendung. Du kannst einige natürlich deaktivieren (auskommentieren), wenn Du diese nicht verwenden möchtest.
Mein Ziel der Docker-Umgebung war es, sie so schlank wie möglich zu halten. Viele andere Docker-Container, die man im Netz finden kann, schleppen unnötigen Ballast mit sich. Das kann u. U. Performance kosten, aber auf jeden Fall auch Speicherplatz.
Meine Docker-Container
- Portainer: Verwaltung der Docker-Umgebung über Port 9000
http://black-pearl.local:9000 - Adminer: Verwaltung der MariaDB über Port 8080
http://black-pearl.local:8080 - Reverseproxy: Einsatz von nginx, so dass FHEM über Port 80 (intern) und 8088 (extern) erreichbar ist und zudem ein Schutz gegen Angriffe von außen besteht.
- FHEM: Hausautomation über Port 8088 (extern) erreichbar, intern nur über den Reverseproxy. Dieser Container wird über eine eigene Dockerfile auf Basis von Alpine Linux erstellt.
- MariaDB: Datenbank zur Speicherung der Daten für die Ausgabe von Graphen. Dieser Container wird über eine eigene Dockerfile auf Basis von Alpine Linux erstellt.
- Alexa-FHEM: Verknüpfung von FHEM und Alexa. Wie das genau geht, findest Du in dem Beitrag FHEM hört jetzt auf Alexa Dieser Container wird über eine eigene Dockerfile auf Basis von Alpine Linux erstellt.
Du findest alle Dateien auch auf GitHub:
https://github.com/krannich/dkDockerFHEM
Meine Ordnerstruktur
- alexa
- config Zertifikat, Public-Key und Konfigurationsdatei
- core Quellcode von Alexa-FHEM
- fhem
- core Quellcode von FHEM (außerhalb vom Container)
- fonts Meteofonts für Statusanzeige auf Kindle
- mariadb
- data Speicherort der Daten (außerhalb vom Container)
- files Konfigurationsdateien und Scripts
- reverseproxy
- conf Konfigurationsdatei
docker-compose.yml
Das Ganze sieht dann in der docker-compose.yml wie folgt aus:
version: '3'
services:
## GENERAL
portainer:
restart: always
image: portainer/portainer:latest
command: -H unix:///var/run/docker.sock --no-auth
ports:
- "9000:9000"
environment:
- REGISTRY_HTTP_TLS_CERTIFICATE=/certs/portainer.crt
- REGISTRY_HTTP_TLS_KEY=/certs/portainer.key
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
- /home/pirate/certs/portainer.key:/certs/portainer.key
- /home/pirate/certs/portainer.crt:/certs/portainer.crt
networks:
- fhem-network
adminer:
image: adminer
restart: always
ports:
- 8080:8080
networks:
- fhem-network
reverseproxy:
restart: always
image: nginx:latest
volumes:
- ./reverseproxy/conf/nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
#- 443:443
- 8088:8088
networks:
- fhem-network
depends_on:
- "fhem"
## FHEM
fhem:
restart: always
expose:
- "8088"
ports:
- "8083:8083"
- "7072:7072"
build: ./fhem
privileged: true
devices:
- "/dev/ttyAMA0:/dev/ttyAMA0"
#- "/dev/ttyUSB0:/dev/ttyUSB0"
volumes:
- ./fhem/core/:/opt/fhem/
- /etc/localtime:/etc/localtime:ro
- /sys/class/gpio:/sys/class/gpio
#- /dev/serial/by-id:/dev/serial/by-id
entrypoint:
- /opt/fhem/start-fhem.sh
networks:
- fhem-network
## SERVICES
mariadb:
restart: always
build: ./mariadb
environment:
MYSQL_ROOT_PASSWORD: fhem1234
ports:
- "3306:3306"
volumes:
- ./mariadb/data:/var/lib/mysql
- ./mariadb/files/init.sql:/docker-entrypoint-initdb.d/fhem-init.sql
networks:
- fhem-network
alexa:
restart: always
ports:
- "3000:3000"
build: ./alexa
volumes:
- ./alexa/config/config.json:/alexa-fhem/config.json
- ./alexa/config/cert.pem:/root/.alexa/cert.pem
- ./alexa/config/key.pem:/root/.alexa/key.pem
networks:
- fhem-network
depends_on:
- "fhem"
volumes:
portainer_data:
networks:
fhem-network:
driver: bridge
Was Du dafür brauchst
Alternative Produkte
So schön ich den Beitrag auch finde, so ärgerlich ist es, das er mitten drin aufhört. Habe nun alle Komponenten (mit Ausnahme der SCC’s) und ein OS laufen, wie geht es denn nun weiter? Nun käme doch die Installation von FHEM in Docker, oder nicht? Brauch ich den Reverse Proxy, den du eingangs angesprochen hast um FHEM zu betreiben?
Moin Thomas,
die weiteren Teile folgen… Habe schon die docker-compose.yal ergänzt. Werde auch noch mein Setup auf Git-Hub veröffentlichen.
Den Reverse-Proxy brauchst Du nicht unbedingt. Ich verwende ihn, da ich Ports nach außen offen habe und das System intern über Port 80 erreichen möchte.
Viele Grüße
Dennis
Moin Moin…
Klasse Beitrag. Beschäftige mich auch gerade mit Docker und FHEM. Wann folgen denn die weiteren Teile? 😉
Viele Grüss
Marco
Hallo Marco,
ich habe noch Vieles in Planung/Vorbereitung. Derzeit habe ich aber massive Probleme mit meiner Hasuautomation, da irgendwie die Funkleistung – vielleicht bedingt durch den Winter – sich verschlechtert hat. Komischerweise ist es in der Docker-Umgebung am schlimmsten. Daher bin ich mir gerade nicht sicher, ob ich diesen Ansatz noch weiter verfolgen sollte. Möchte ungerne etwas empfehlen, wenn ich selbst nicht überzeugt davon bin.
Kennst Du vielleicht solche Probleme auch?
Viele Grüße
Dennis
Da sich schon länger nichts mehr verändert hat, gehe ich davon aus, dass das Projekt nicht mehr weiter verfolgt wird.
Ich bin auch im Überlegen Fhem auf Docker zu bringen, allerdings nicht auf einem Raspberry, sondern auf einem ThinClient Rechner mit 4GB RAM und 32GB SSD, AMD QuadCore mit 1,5 Ghz.
Bitte um ein Status-Update
Danke
Viele Grüße
Georg