-
-
Notifications
You must be signed in to change notification settings - Fork 192
Installation Docker OCI
It is possible to run RaspberryMatic also as a docker/OCI container on existing amd64, aarch64/arm64 or arm-based systems. While the docker version comes with almost all functionality that a "normal" RaspberryMatic system provides, some functionality like, e.g. the network setup or WebUI-based update mechanism has been explicitly disabled since these operations are usually performed on the system hosting the docker container itself rather than within the container.
Furthermore, while almost the same hardware requirements in terms of homematic rf-modules apply like with a standard RaspberryMatic system, the kernel drivers for, e.g. the RPI-RF-MOD
, HM-MOD-RPI-PCB
or HmIP-RFUSB
as well as for the HB-RF-USB
/HB-RF-USB-2
and the HB-RF-ETH
have to be installed on the hosting machine rather than within the container. The container then just uses these preloaded kernel drivers.
This driver installation can be either performed using a dedicated install-docker.sh
installation script or manually. In either cases, kernel modules are installed that are kindly developed and distributed by the author of piVCCU (@alexreinert).
Important
To be able to communicate with a HmIP-HAP
or HmIPW-DRAP
device, the docker container implementation outlined here utilizes a macvlan
docker network which makes it necessary to have two static ip addresses (<IP-ADDRESS>
and <AUX-ADDRESS
) available from your local network which are outside of any DHCP range (e.g. NOT supplied by your router) and are exclusively assigned to the docker container as well as to your docker host so that both systems (docker host and container) can communicate with eachother.
- Ensure you have docker installed on your host system (where the container will run on):
sudo sh -c "wget -qO - https://get.docker.com | bash -"
- Make sure to add the current user to the
docker
group so that it can execute docker commands:sudo usermod -aG docker $USER exec su -l $USER
- Make sure the docker environment works correctly by executing the
hello-world
example docker:docker run hello-world
After having applied these steps your host system should be equipped to run all common docker containers.
For installing all necessary requirements to create and run the RaspberryMatic docker container one can either use an automatic script-based method (install-docker.sh
) or follow manual installation steps which use either docker pull
, docker load
or even a docker compose
based approach to run/manage the RaspberryMatic container.
Please note, that in the following documentation sections one has to specify/replace certain placeholders like <IP-ADDRESS>
, <INTERFACE>
, etc. with their respective substitutions in configuration files, scripts or executions of helper scripts. To chose the right substitution values for these placeholders they are explained here:
-
<IP-ADDRESS>
: a manually chosen static ip address (e.g.192.168.178.4
) which will be assigned to the docker container. Make sure to chose an ip address from your normal LAN subnet which is NOT part of your normal DHCP assignable range your router normally supplies to network clients. -
<AUX-ADDRESS>
: a manually chosen static ip address (e.g.192.168.178.3
) which will be used as an additional so-called auxiliary ip address for your docker host system (where the container will run on) so that it can communicate with the docker container on the same subnet. Make sure to chose an ip address from your normal LAN subnet which is NOT part of your normal DHCP assignable range your router normally supplies to network clients. Also make sure to NOT use the same IP address like the host is already using. -
<INTERFACE>
: the name of the network interface (e.g.eth0
) on your docker host system which is used to communicate with your LAN (should be automatically identified). -
<SUBNET>
: the subnet specifier (e.g.192.168.178.0/24
) of your normal LAN (should be automatically identified). -
<GATEWAY>
: the ip address of the default gateway (e.g.192.168.178.1
) of your normal LAN (should be automatically identified).
For users with a lower amount of Linux or docker knowledge or for users who want to use an easy installation procedure, a dedicated all-in-one installation script (install-docker.sh
) can be used to install all additional prerequisites for the RaspberryMatic container so that it can be correctly created and will run on the docker equipped host system:
-
Execute the following command to install all necessary dependencies and create the container:
wget -qO - https://raspberrymatic.de/install-docker.sh | bash -
The script will make sure all dependencies are installed and might request
sudo
rights to do so. If this is the case and the script notifies to do so please re-run it withsudo
rights accordingly:sudo sh -c "wget -qO - https://raspberrymatic.de/install-docker.sh | bash -"
In addition, this script might request some additional information from you, like specifying a reserved ip address (
<IP-ADDRESS>
) which will be assigned to the container as well as a so-called auxiliary ip address (<AUX-ADDRESS>
) which will be assigned to the host system itself so that it can communicate with the started docker container. Furthermore, it will try to identify the network interface (<INTERFACE>
), the subnet (<SUBNET>
) and the default gateway ip (<GATEWAY>
) automatically, but allows a user to change it during the installation procedure. -
After the script has created the docker container you should be able to start the container using:
docker start -i ccu
NOTE: Omit
-i
if you want to start the container non-interactive and put it in background.
This script can also be used from time to time to ensure the docker installation is still correct or according to the lastest changes of RaspberryMatic. Furthermore, in case you run into some issues (e.g. because you updated the host system itself) this script could help to get the docker environment running again. Make sure, however, to update the script over time (in case you downloaded it) because we might introduce changes to it as we move forward.
If you prefer to install all prerequisites, dependencies manually on your docker host system as well as prefer to create the docker container manually or if you are using docker solutions like docker compose
, please make sure to following the following procedure in a step-by-step manner.
To install all necessary third-party dependencies on the docker host system for the RaspberryMatic container to work correctly the following step have to be performed one after another:
-
Install pivccu-modules-dkms kernel modules (required for
RPI-RF-MOD
,HM-MOD-RPI-PCB
orHmIP-RFUSB
use) by executing:sudo apt install wget ca-certificates build-essential bison flex libssl-dev gpg wget -qO - https://apt.pivccu.de/piVCCU/public.key | sudo gpg --dearmor -o /usr/share/keyrings/pivccu-archive-keyring.gpg sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/pivccu-archive-keyring.gpg] https://apt.pivccu.de/piVCCU stable main" >/etc/apt/sources.list.d/pivccu.list' sudo apt update sudo apt install pivccu-modules-dkms
-
If you are using a RaspberryPi and want to use a
RPI-RF-MOD
orHM-MOD-RPI-PCB
connected to GPIO (NOT necessary if you want to use aHB-RF-USB
,HB-RF-USB-2
,HB-RF-ETH
orHmIP-RFUSB
):-
Install the necessary device tree patches:
sudo apt install pivccu-modules-raspberrypi
-
Disable bluetooth:
sudo bash -c 'cat <<EOT >>/boot/config.txt dtoverlay=disable-bt EOT' systemctl is-active --quiet hciuart.service && sudo systemctl disable hciuart.service
NOTE: If there is no
/boot/config.txt
, you may put these changes under/boot/firmware/usercfg.txt
-
Disable serial console
sudo sed -i /boot/cmdline.txt -e "s/console=\(serial0\|ttyAMA0\),[0-9]\+ //"
And alternative method (if you run into problems) for disabling the serial console or
ttyAMA0
would be to run the following script:sudo bash -c 'cat <<EOT >>/boot/config.txt dtoverlay=miniuart-bt core_freq=250 EOT'
NOTE: If there is no
/boot/config.txt
, you may put these changes under/boot/firmware/usercfg.txt
Disable and mask any serial getty service under your OS so that ttyAMA0 will be free:
sudo systemctl stop [email protected] && sudo systemctl disable [email protected] && sudo systemctl mask [email protected]
-
-
If you are using a
HmIP-RFUSB
, make sure you DO NOT have a file/etc/udev/rules.d/10-hmiprfusb.rules
installed, otherwise delete it:sudo rm -f /etc/udev/rules.d/10-hmiprfusb.rules
-
Make sure to execute the following so that a
/etc/udev/rules.d/99-Homematic.rules
udev rule file is created with the right entries:sudo bash -c 'cat <<EOF >/etc/udev/rules.d/99-Homematic.rules ATTRS{idVendor}=="1b1f" ATTRS{idProduct}=="c020", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="1b1f" ATTRS{idProduct}=="c00f", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="0403" ATTRS{idProduct}=="6f70", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="10c4" ATTRS{idProduct}=="8c07", ENV{ID_MM_DEVICE_IGNORE}="1" EOF'
-
Install
eq3_char_loop
kernel module to automatic module load section:sudo sh -c 'echo eq3_char_loop >/etc/modules-load.d/eq3_char_loop.conf'
-
Start+Load all necessary kernel modules on host:
sudo service pivccu-dkms start sudo modprobe eq3_char_loop
NOTE: If
modprobe eq3_char_loop
fails it could be necessary to update the kernel-headers (especially on Raspberry Pi OS 64-bit):sudo apt update sudo apt install raspberrypi-kernel raspberrypi-kernel-headers raspberrypi-bootloader
Afterwards you may have to execute the
pivccu-dkms
installation again and also install theeq3_char_loop
kernel module to the automatic module load section:sudo apt install pivccu-modules-dkms sudo sh -c 'echo eq3_char_loop >/etc/modules-load.d/eq3_char_loop.conf'
-
Create a dedicated
macvlan
docker network namedccu
for the RaspberryMatic container to use (can be skipped if you are going to use thedocker compose
method to setup and run the container):docker network create -d macvlan \ --opt parent=<INTERFACE> \ --subnet <SUBNET> \ --gateway <GATEWAY> \ ccu
NOTE: Make sure to adapt the values for all
<XXX>
placeholder accordingly (see above). -
Setup a "shim" network link so that the docker host itself can access the docker container, which usually isn't the case because of network encapsulation:
sudo ip link add ccu-shim link <INTERFACE> type macvlan mode bridge sudo ip addr add <AUX-ADDRESS> dev ccu-shim sudo ip link set ccu-shim up sudo ip route add <IP-ADDRESS> dev ccu-shim protocol static
NOTE: Make sure to adapt the values for all
<XXX>
placeholder accordingly (see above).The above
ip
commands to create a shim network have to be usually executed manually after each reboot of the docker host system because they are not persistent. You have to either execute them each time or add them to a boot-up like script which will be executed on each boot.E.g. on Ubuntu/Debian the following content can be put into the file
/etc/network/if-up.d/99-ccu-shim-network
#!/bin/sh if [ "$IFACE" = "<INTERFACE>" ]; then if ! ip link show ccu-shim >/dev/null 2>&1; then ip link add ccu-shim link <INTERFACE> type macvlan mode bridge ip addr add <AUX-ADDRESS> dev ccu-shim ip link set ccu-shim up ip route add <IP-ADDRESS> dev ccu-shim protocol static fi fi
NOTE: Make sure to set executable rights (
chmod a+rx /etc/network/if-up.d/99-ccu-shim-network
) to that file and to replace all<XXX>
tags with the appropriate values from above.
For finally creating the docker container one can use different manual methods (docker pull
, docker load
and docker compose
) or use the above mentioned self-container install-docker.sh
solution. For the manual container setup/create one can use the following different solutions (make sure to replace all <XXX>
placeholder accordingly):
- Use
docker pull
to retrieve the latest version:docker pull ghcr.io/jens-maus/raspberrymatic:latest
- Create the raspberrymatic docker container:
docker create --name ccu \ --read-only \ --volume ccu_data:/usr/local:rw \ --volume /lib/modules:/lib/modules:ro \ --volume /run/udev/control:/run/udev/control \ --privileged --restart always --stop-timeout 30 \ --network ccu --ip <IP-ADDRESS> --hostname ccu \ ghcr.io/jens-maus/raspberrymatic:latest
- Start the docker container:
NOTE: Omit
docker start -i ccu
-i
if you want to start the container non-interactive and put it in background.
- Download the latest docker/oci image version of RaspberryMatic:
wget https://github.com/jens-maus/RaspberryMatic/releases/download/3.XX.XX.YYYYMMDD/RaspberryMatic-3.XX.XX.YYYYMMDD-oci_amd64.tgz
- Use
docker load
to load the downloaded into the docker environment:docker load < RaspberryMatic-3.XX.XX.YYYYMMDD-oci_amd64.tgz
- Run the raspberrymatic docker using cmd-line:
docker create --name ccu \ --read-only \ --volume ccu_data:/usr/local:rw \ --volume /lib/modules:/lib/modules:ro \ --volume /run/udev/control:/run/udev/control \ --privileged --restart always --stop-timeout 30 \ --network ccu --ip <IP-ADDRESS> --hostname ccu \ ghcr.io/jens-maus/raspberrymatic:amd64-3.XX.XX.YYYYMMDD
- Start the docker container:
NOTE: Omit
docker start -i ccu
-i
if you want to start the container non-interactive and put it in background.
- Add the following to your
docker-compose.yml
:version: "3.8" services: raspberrymatic: image: ghcr.io/jens-maus/raspberrymatic:latest container_name: ccu hostname: ccu read_only: true privileged: true restart: unless-stopped stop_grace_period: 30s volumes: - ccu_data:/usr/local:rw - /lib/modules:/lib/modules:ro - /run/udev/control:/run/udev/control networks: ccu: ipv4_address: <IP-ADDRESS> volumes: ccu_data: networks: ccu: name: ccu driver: macvlan driver_opts: parent: <INTERFACE> ipam: config: - subnet: <SUBNET> gateway: <GATEWAY>
- Start your docker compose environment:
docker compose up -d
-
If you get
ERROR: could not insert 'eq3_char_loop': Exec format error
messages during startup the required kernel modules could not be correctly compiled on your docker host machine. To solve that issue you can try the following procedure:sudo apt remove --purge linux-headers-* sudo rm -rf /usr/src/linux-header-* sudo apt autoremove && sudo apt autoclean sudo apt install linux-headers-generic sudo apt install --reinstall pivccu-modules-dkms
-
In case radio communication takes sometimes up to several seconds or randomly fails ensure the container instance has enough cpu shares to process radio messages in time. This can be done by adding
--cap=sys_nice
and tweaking--cpu-reserved
and/or--cpu-shares
in yourdocker run
command line or by adding the following in yourdocker-compose.yml
:raspberrymatic: ... cap_add: - SYS_NICE cpu_shares: 4096 # 4x more cpu cycles than standard containers during busy peaks deploy: update_config: order: stop-first resources: reservations: cpus: '0.6' memory: 256M
-
(partly obsolete): If during container startup you receive
cpu.rt_runtime_us == 0
errors in thedocker logs ccu
output of your RaspberryMatic startup, your host system is using a linux kernel withCONFIG_RT_GROUP_SCHED
real-time scheduling capabilities and did not assign enough real-time shares to the docker daemon, thus the RaspberryMatic container.- Modify/Create the
/etc/docker/daemon.json
file to contain/look like:Afterwards, make sure you restart the docker daemon accordingly (e.g.{ "cpu-rt-runtime": 950000 }
sudo systemctl restart docker
). - Depending on the method you are using to start the RaspberryMatic docker container make sure to either
-
If using
install-docker.sh
:No action required as the latest
install-docker.sh
script should automatically set the necessary additional command-line options. -
If using
docker pull
ordocker load
:add the following command-line options to the corresponding
docker run ...
command:--cpu-rt-runtime 950000 --ulimit rtprio=99
-
If using
docker compose
:add the following options to your
docker-compose.yml
file:cpu_rt_runtime: 950000 ulimits: rtprio: 99
-
- Modify/Create the
After startup, point your web browser to the IP of your hosting system and with port :80
and the usual CCU WebUI should be accessible:
http://<IP-ADDRESS>/
After startup, you can either access the container via enabling SSH access to it in the CCU WebUI or you use the following docker exec
command to be able to use the command-line:
docker exec -it ccu /bin/sh
The RaspberryMatic docker has to be updated from the host machine (the recommended "docker way"). Use either the same instructions like in using install-docker.sh
and the other subsections (e.g. using docker pull
) so that you retrieve the very latest version of the RaspberryMatic docker with the next execution.
If you decide to get rid of the whole RaspberryMatic container installation or if you would like to cleanup before trying to install the container in a fresh environment you can do so by running the install-docker.sh
script with an uninstall
parameter:
wget -qO - https://raspberrymatic.de/install-docker.sh | sudo bash -s uninstall
This command will make sure to uninstall, remove and purge all relevant configuration files, docker container and docker network dependencies so that after a fresh reboot of your docker host system only the user data volume should still be present.
You can pass variables to the install-docker.sh
script to change the defaults upon runtime:
-
CCU_DATA_VOLUME
- Name of the docker volume where CCU data will persist. It can be a local location as well such as a mounted NAS folder, cluster fs (glusterfs), etc.
- Default: "ccu_data"
-
CCU_OCI_REPO
- Container repository to use
- Default: "ghcr.io/jens-maus/raspberrymatic"
-
CCU_OCI_TAG
- Container image tag to use
- Default: "latest"
-
CCU_CONTAINER_NAME
- Name of the container instance. Will also be used as
--hostname
parameter for docker run. - Default: "ccu"
- Name of the container instance. Will also be used as
-
CCU_CONTAINER_IP
- IP address for the container instance (e.g.
192.168.178.4
). Have to be a non-DHCP assignable IP address from the same LAN subnet as the docker host. - Default: "" (will be interactively requested)
- IP address for the container instance (e.g.
-
CCU_CONTAINER_IP_AUX
- Auxiliary ip address additionally assigned to the docker host system (e.g.
192.168.178.3
). Have to be a non-DHCP assignable IP address from the same LAN subnet as the main IP address of the docker host. - Default: "" (will be interactively requested)
- Auxiliary ip address additionally assigned to the docker host system (e.g.
-
CCU_NETWORK_NAME
- Name for the docker
macvlan
network being created/maintained. - Default: "ccu"
- Name for the docker
-
CCU_NETWORK_INTERFACE
- Interface name (e.g.
eth0
,ensXX
) of the main interface the docker host is running on and on which the same subnet is located. - Default: "" (will be automatically determined or interactively requested)
- Interface name (e.g.
-
CCU_NETWORK_SUBNET
- Subnet (e.g.
192.168.178.0/24
) of the main docker host and container ip address being used. - Default: "" (will be automatically determined or interactively requested)
- Subnet (e.g.
-
CCU_NETWORK_GATEWAY
- Gateway ip address (e.g.
192.168.178.1
) of the main docker host being used. - Default: "" (will be automatically determined or interactively requested)
- Gateway ip address (e.g.
-
CCU_DOCKER_RUN_OPTIONS
- Additional options for docker run
- Default: ""
-
CCU_DOCKER_PULL_OPTIONS
- Additional options for docker pull run
- Default: ""
-
CCU_DOCKER_PULL_REFRESH
- Do a docker pull to refresh image
- Default: "true"
-
CCU_DOCKER_STOP_TIMEOUT
- time allowed to stop the container before Docker kills it
- Default: 30 (seconds)
Table of Contents RaspberryMatic Documentation © 2015-2024 Jens Maus and RaspberryMatic Contributors, licensed under CC BY-SA License 4.0