Installation Docker OCI - OpenCCU/OpenCCU GitHub Wiki

OpenCCU kann als Docker/OCI-Container auf bestehenden amd64- bzw. arm64 (aarch64)-Systemen betrieben werden. Der Container bietet nahezu den vollen Funktionsumfang eines „normalen“ OpenCCU-Systems; bestimmte Funktionen – etwa die Netzwerkeinrichtung oder der WebUI-basierte Update-Mechanismus – sind jedoch bewusst deaktiviert, da diese Aufgaben üblicherweise auf dem Host-System und nicht innerhalb des Containers erledigt werden.

Wie bei einer regulären OpenCCU-Installation werden passende Homematic-Funkmodule benötigt. Die zugehörigen Kernel-Treiber für Funkmodule wie RPI-RF-MOD, HM-MOD-RPI-PCB, HmIP-RFUSB sowie für die Adapter HB-RF-USB / HB-RF-USB-2 und HB-RF-ETH müssen dabei jedoch auf dem Host und nicht im Container installiert werden; der Container nutzt dann diese bereits geladenen Treiber. Die Treiber lassen sich entweder über das Skript install-docker.sh oder manuell installieren. In beiden Fällen werden die von @alexreinert über piVCCU bereitgestellten Kernel-Module auf dem Host installiert.

Important

Bekannte Einschränkungen

Damit OpenCCU mit einem HmIP-HAP oder HmIPW-DRAP kommunizieren kann, verwendet die folgende Anleitung ein macvlan-Docker-Netzwerk. Dafür werden zwei statische IP-Adressen – <IP-ADDRESS> und <AUX-ADDRESS> – aus dem lokalen Netzwerk benötigt, die außerhalb des DHCP-Bereichs des Routers liegen. <IP-ADDRESS> wird dem Container und <AUX-ADDRESS> dem Docker-Host zugewiesen, damit Host und Container einander erreichen können.


Voraussetzungen

  • Ein Debian-basiertes amd64- oder arm64-Host-System (z. B. Debian, Ubuntu, Raspberry Pi OS 64-Bit, Armbian). 32-Bit-Systeme werden seit OpenCCU 3.87.6.20260313 nicht mehr unterstützt.
  • Eine aktuelle Version der Kernel-Module pivccu-modules-dkms (mindestens 1.0.88). Ältere Versionen führen dazu, dass der Homematic IP-Dienst im Container nicht startet bzw. ein HmIP-RFUSB-TK nicht erkannt wird.
  • Ein unterstütztes Funkmodul.

Docker auf dem Host installieren und vorbereiten:

  1. Docker installieren:
    sudo sh -c "wget -qO - https://get.docker.com | bash -"
  2. Benutzer der Gruppe docker hinzufügen, damit er Docker-Kommandos ausführen darf:
    sudo usermod -aG docker $USER
    exec su -l $USER
  3. Docker-Funktion prüfen mit dem hello-world-Beispiel:
    docker run hello-world

Danach ist der Host bereit für den Betrieb von Docker-Containern.


Installation

Zur Einrichtung aller Voraussetzungen und zum Starten des OpenCCU-Containers kann entweder das Skript install-docker.sh verwendet oder manuell mit docker pull, docker load oder Docker Compose vorgegangen werden.

Verwendete Platzhalter – durch die Werte der eigenen Umgebung ersetzen:

  • <IP-ADDRESS> – die statische IP-Adresse (z. B. 192.168.178.4) des Containers; außerhalb des DHCP-Bereichs.
  • <AUX-ADDRESS> – eine zusätzliche statische IP-Adresse (z. B. 192.168.178.3) für den Host, damit Host und Container im selben Subnetz kommunizieren können; ebenfalls außerhalb des DHCP-Bereichs und nicht die Haupt-IP des Hosts.
  • <INTERFACE> – das primäre Netzwerkinterface des Hosts (z. B. eth0).
  • <SUBNET> – das Subnetz des lokalen Netzwerks (z. B. 192.168.178.0/24).
  • <GATEWAY> – die IP-Adresse des Standard-Gateways (z. B. 192.168.178.1).

Automatische Installation

Für eine möglichst einfache Einrichtung (oder bei wenig Linux-/Docker-Erfahrung) empfiehlt sich das Installationsskript:

  1. Ausführen:

    wget -qO - https://openccu.de/install-docker.sh | bash -

    Fordert das Skript erweiterte Rechte an, erneut mit sudo ausführen:

    sudo sh -c "wget -qO - https://openccu.de/install-docker.sh | bash -"

    Während der Installation fragt das Skript ggf. folgende Werte ab:

    • <IP-ADDRESS> – IP-Adresse des Containers (statisch, außerhalb DHCP)
    • <AUX-ADDRESS> – zusätzliche IP-Adresse des Hosts (statisch, außerhalb DHCP)
    • <INTERFACE>, <SUBNET>, <GATEWAY> – werden automatisch ermittelt, können aber angepasst werden
  2. Container starten:

    docker start -i ccu

    Hinweis: Ohne -i startet der Container im Hintergrund.

Das Skript kann jederzeit erneut ausgeführt werden, um die Docker-Einrichtung zu prüfen, an Änderungen in OpenCCU anzupassen oder OpenCCU zu aktualisieren. Weitere Einstellmöglichkeiten des Skripts sind im Anhang beschrieben.

Manuelle Installation

Für volle Kontrolle (oder bei Verwendung von Werkzeugen wie Docker Compose) wie folgt vorgehen.

Abhängigkeiten auf dem Host

Folgende Abhängigkeiten auf dem Docker-Host installieren, damit der OpenCCU-Container korrekt auf die Homematic-Funkhardware zugreifen kann:

  1. pivccu-modules-dkms installieren (Treiber für RPI-RF-MOD, HM-MOD-RPI-PCB, HmIP-RFUSB sowie HB-RF-USB(-2)/HB-RF-ETH):

    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

    Für das Übersetzen der Module werden die Kernel-Header des laufenden Kernels benötigt, z. B. linux-headers-rpi-v8 unter Raspberry Pi OS (64-Bit) bzw. linux-headers-$(uname -r) unter Debian/Ubuntu.

  2. GPIO-Funkmodul (RPI-RF-MOD / HM-MOD-RPI-PCB) – nicht erforderlich bei HB-RF-USB, HB-RF-USB-2, HB-RF-ETH oder HmIP-RFUSB:

    • Armbian: Device-Tree-Overlays installieren:
      sudo apt install pivccu-devicetree-armbian
    • Raspberry Pi OS:
      1. Device-Tree-Overlays installieren:
        sudo apt install pivccu-modules-raspberrypi
      2. Serielle Schnittstelle für das Funkmodul freigeben (nicht beim Raspberry Pi 5): Beim Raspberry Pi 3/4 belegt das integrierte Bluetooth die serielle Schnittstelle (ttyAMA0), die das Funkmodul an GPIO 14/15 benötigt.
        • Variante A (empfohlen, entspricht der Konfiguration von OpenCCU selbst): Bluetooth auf die Mini-UART verlegen; Bluetooth bleibt eingeschränkt nutzbar.
          sudo bash -c 'cat <<EOT >>/boot/firmware/config.txt
          enable_uart=1
          dtoverlay=miniuart-bt
          EOT'
        • Variante B (falls Bluetooth nicht benötigt wird oder Probleme auftreten): Bluetooth vollständig deaktivieren.
          sudo bash -c 'cat <<EOT >>/boot/firmware/config.txt
          dtoverlay=disable-bt
          EOT'
          sudo systemctl disable hciuart
      3. Serielle Konsole deaktivieren:
        sudo sed -i /boot/firmware/cmdline.txt -e "s/console=\(serial0\|ttyAMA0\),[0-9]\+ //"
        sudo systemctl stop [email protected] && sudo systemctl disable [email protected] && sudo systemctl mask [email protected]
      Hinweis: Bei älteren Raspberry-Pi-OS-Versionen liegen die Dateien config.txt bzw. cmdline.txt direkt unter /boot/.
  3. HmIP-RFUSB – sicherstellen, dass keine kollidierende udev-Regel vorhanden ist:

    sudo rm -f /etc/udev/rules.d/10-hmiprfusb.rules
  4. udev-Regeln für Homematic-Geräte anlegen:

    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'
  5. eq3_char_loop beim Systemstart laden:

    sudo sh -c 'echo eq3_char_loop >/etc/modules-load.d/eq3_char_loop.conf'
  6. Kernel-Module jetzt starten/laden:

    sudo service pivccu-dkms start
    sudo modprobe eq3_char_loop

    Hinweis: Schlägt modprobe eq3_char_loop fehl, die Kernel-Header installieren bzw. aktualisieren (siehe Schritt 1) und die Module neu übersetzen:

    sudo apt install --reinstall pivccu-modules-dkms
  7. macvlan-Netzwerk mit dem Namen ccu anlegen (entfällt bei Verwendung von Docker Compose, siehe unten):

    docker network create -d macvlan \
                          --opt parent=<INTERFACE> \
                          --subnet <SUBNET> \
                          --gateway <GATEWAY> \
                          ccu
  8. „Shim“-Verbindung einrichten, damit der Host den Container erreichen kann (macvlan trennt Host und Container standardmäßig):

    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

    Diese ip-Kommandos sind nicht dauerhaft; sie müssen bei jedem Systemstart ausgeführt bzw. in ein Startskript übernommen werden.

    Beispiel für Debian/Ubuntu mit ifupdown – Datei /etc/network/if-up.d/99-ccu-shim-network anlegen:

    #!/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

    Danach:

    sudo chmod a+rx /etc/network/if-up.d/99-ccu-shim-network

    Beispiel für Systeme mit NetworkManager (z. B. Raspberry Pi OS):

    sudo nmcli connection add type macvlan con-name ccu-shim ifname ccu-shim mode bridge dev <INTERFACE>
    sudo nmcli connection modify ccu-shim ipv4.addresses "<AUX-ADDRESS>"
    sudo nmcli connection modify ccu-shim ipv4.method manual
    sudo nmcli connection modify ccu-shim +ipv4.routes "<IP-ADDRESS>"
    sudo nmcli connection modify ccu-shim connection.autoconnect yes
    sudo nmcli connection up ccu-shim

    Kontrolle, ob die Einstellungen korrekt übernommen wurden:

    nmcli device status
    ip route show

Container einrichten / starten

Der Container kann über docker pull, docker load oder Docker Compose (bzw. über das Skript install-docker.sh) eingerichtet werden. Alle <…>-Platzhalter entsprechend ersetzen.

Mit docker pull
  1. Aktuelles Image herunterladen:
    docker pull ghcr.io/openccu/openccu:latest
  2. Container anlegen:
    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/openccu/openccu:latest
  3. Starten:
    docker start -i ccu
    Hinweis: Ohne -i startet der Container im Hintergrund.
Mit docker load
  1. Aktuelles OpenCCU-Docker/OCI-Image herunterladen (für arm64-Hosts oci_arm64 statt oci_amd64 verwenden):
    wget https://github.com/OpenCCU/OpenCCU/releases/download/3.XX.XX.YYYYMMDD/OpenCCU-3.XX.XX.YYYYMMDD-oci_amd64.tgz
  2. In Docker laden:
    docker load < OpenCCU-3.XX.XX.YYYYMMDD-oci_amd64.tgz
  3. Container anlegen:
    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/openccu/openccu:amd64-3.XX.XX.YYYYMMDD
  4. Starten:
    docker start -i ccu
    Hinweis: Ohne -i startet der Container im Hintergrund.
Mit Docker Compose
  1. Folgendes in die docker-compose.yml aufnehmen:
    services:
      openccu:
        image: ghcr.io/openccu/openccu: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>
  2. Mit Compose starten:
    docker compose up -d

Mögliche Fehler beim Start des Containers

  1. ERROR: could not insert 'eq3_char_loop': Exec format error Die notwendigen Kernel-Module konnten nicht für den Host-Kernel übersetzt werden. Abhilfe:

    sudo apt remove --purge linux-headers-*
    sudo rm -rf /usr/src/linux-headers-*
    sudo apt autoremove && sudo apt autoclean
    sudo apt install linux-headers-generic
    sudo apt install --reinstall pivccu-modules-dkms

    (Unter Raspberry Pi OS statt linux-headers-generic das Paket linux-headers-rpi-v8 installieren.)

  2. Homematic IP-Dienst startet nicht bzw. HmIP-RFUSB-TK wird nicht erkannt Die Kernel-Module auf dem Host sind zu alt. pivccu-modules-dkms auf mindestens Version 1.0.88 aktualisieren:

    sudo apt update && sudo apt install --only-upgrade pivccu-modules-dkms
  3. Langsame oder unzuverlässige Funkkommunikation Sicherstellen, dass der Container genügend CPU-Zeit erhält, um Funktelegramme rechtzeitig zu verarbeiten. Dazu z. B. --cap-add=SYS_NICE sowie CPU-Einstellungen beim docker create ergänzen, bzw. in Compose:

    openccu:
      # ...
      cap_add:
        - SYS_NICE
      cpu_shares: 4096  # 4x mehr CPU-Zyklen in Lastspitzen
      deploy:
        update_config:
          order: stop-first
        resources:
          reservations:
            cpus: '0.6'
            memory: 256M
  4. (Teilweise veraltet) Fehler cpu.rt_runtime_us == 0 in docker logs ccu Der Host-Kernel wurde mit CONFIG_RT_GROUP_SCHED übersetzt und der Docker-Daemon verfügt über zu wenig Echtzeit-Laufzeit.

    • Option für den Docker-Daemon in /etc/docker/daemon.json setzen:

      {
        "cpu-rt-runtime": 950000
      }

      Danach Docker neu starten: sudo systemctl restart docker.

    • Je nach Installationsweg zusätzlich:

      • install-docker.sh: in aktuellen Versionen nicht erforderlich.
      • docker pull / docker load: beim Anlegen des Containers ergänzen:
        --cpu-rt-runtime 950000 --ulimit rtprio=99
      • Docker Compose (docker-compose.yml):
        cpu_rt_runtime: 950000
        ulimits:
          rtprio: 99

Nutzung des Containers

WebUI-Zugriff

Im Browser die IP-Adresse des Containers aufrufen:

http://<IP-ADDRESS>/

Anschließend helfen die ersten Schritte nach der Installation bei der weiteren Einrichtung.

Shell-Zugriff

Entweder SSH in der WebUI aktivieren oder:

docker exec -it ccu /bin/sh

Update auf neuere Versionen

Updates erfolgen vom Host aus (auf dem für Docker üblichen Weg) mit demselben Verfahren wie bei der Installation – also durch erneutes Ausführen von install-docker.sh, per docker pull mit anschließendem Neuanlegen des Containers oder über Docker Compose (docker compose pull && docker compose up -d). Die Konfiguration im Volume ccu_data bleibt dabei erhalten.


Deinstallation

Um die gesamte OpenCCU-Container-Einrichtung zu entfernen (inklusive Netzwerke und Konfigurationen auf dem Host), das Installationsskript mit dem Parameter uninstall aufrufen:

wget -qO - https://openccu.de/install-docker.sh | sudo bash -s uninstall

Dabei werden Container, Netzwerke und zugehörige Konfigurationsdateien entfernt. Nach einem Neustart sollte nur noch das Daten-Volume (ccu_data) übrig sein, das bei Bedarf mit docker volume rm ccu_data gelöscht werden kann.


Anhang

Weitere Einstellungen für install-docker.sh

Über Umgebungsvariablen lassen sich die Voreinstellungen des Skripts anpassen:

  • CCU_DATA_VOLUME Name des Docker-Volumes für die persistenten CCU-Daten (kann auch auf ein eingebundenes NAS, ein Cluster-Dateisystem usw. zeigen). Standard: ccu_data

  • CCU_OCI_REPO Zu verwendendes Container-Image-Repository. Standard: ghcr.io/openccu/openccu

  • CCU_OCI_TAG Tag des Container-Images. Standard: latest

  • CCU_CONTAINER_NAME Name der Container-Instanz (wird auch als --hostname verwendet). Standard: ccu

  • CCU_CONTAINER_IP Statische IP-Adresse des Containers (z. B. 192.168.178.4), außerhalb des DHCP-Bereichs. Standard: (leer; wird interaktiv abgefragt)

  • CCU_CONTAINER_IP_AUX Zusätzliche IP-Adresse des Hosts (z. B. 192.168.178.3), im selben Subnetz, außerhalb des DHCP-Bereichs. Standard: (leer; wird interaktiv abgefragt)

  • CCU_NETWORK_NAME Name des Docker-macvlan-Netzwerks. Standard: ccu

  • CCU_NETWORK_INTERFACE Netzwerkinterface des Hosts (z. B. eth0, ensXX). Standard: (automatisch ermittelt bzw. interaktiv abgefragt)

  • CCU_NETWORK_SUBNET Subnetz (z. B. 192.168.178.0/24). Standard: (automatisch ermittelt bzw. interaktiv abgefragt)

  • CCU_NETWORK_GATEWAY IP-Adresse des Gateways (z. B. 192.168.178.1). Standard: (automatisch ermittelt bzw. interaktiv abgefragt)

  • CCU_DOCKER_RUN_OPTIONS Zusätzliche Optionen für docker run. Standard: (leer)

  • CCU_DOCKER_PULL_OPTIONS Zusätzliche Optionen für docker pull. Standard: (leer)

  • CCU_DOCKER_PULL_REFRESH Ob das Image per docker pull aktualisiert werden soll. Standard: true

  • CCU_DOCKER_STOP_TIMEOUT Zeit (in Sekunden), die dem Container zum Beenden gewährt wird, bevor Docker ihn zwangsweise stoppt. Standard: 30

⚠️ **GitHub.com Fallback** ⚠️