Schon vor ca. 2 Jahren habe ich mich dazu entschlossen, die im Rahmen des smartHOMES erforderlichen Services zu „dockerisieren“ (Docker Container). Welche Stolpersteine es dabei zu berücksichtigen gilt, kurz in diesem Beitrag.
Docker ist eine feine Sache, wenn es darum geht einzelne Dienste (Microservices) auf einem Host und somit im heimischen Netzwerk bereitzustellen. In der Community finden sich zahlreiche Beispiele und Vorgehensweisen.
Aber auch wenn Docker darauf ausgelegt ist, einzelne Dienste auf einem Host zu isolieren, kann sich dieses mitunter negativ auf den Host selbst auswirken. Das ist genau dann der Fall, wenn man die einzelnen Container (Dienste) nicht entsprechend konfiguriert und diese sich im schlimmsten Fall die gesamten zur Verfügung stehen Ressourcen des Host zu Nutze machen.
Stellt man neue Services in Form einzelner Container bereit, so bedienen sich diese standardmässig an allen zur Verfügung stehen Ressourcen wie RAM, CPU und Speicherplatz. Das kann gut gehen – muss es aber nicht. Dieses ist immer ein wenig vom ganzheitliche Setup abhängig. Wenn auch nur ein Dienst aus der Reihe tanzt, ist es schnell vorbei mit einem performanten und zuverlässigen System.
Bevor man also anfängt und „unbedacht“ zahlreiche Dienste dockerisiert, sollte man etwas recherchieren und sich über die jeweiligen Anforderungen an den Host schlau machen.
Mein Setup
Am Beispiel meines eigenen Setups werde ich einmal zeigen, wie eine Konfiguration aussehen könnte.
Als Docker Host dient ein kleiner, aber dennoch feiner Mini PC aus dem Hause DELL. Dieser verfügt über eine i5 4 Kern CPU, 8 GB RAM sowie eine 512GB SSD HDD. In Summe zeigt sich der Host recht sparsam, wenn es um die Energieaufnahme geht. Immerhin verrichtet dieser 24/7 seinen Dient im heimischen Netz.
Folgende Dienste werden über den Host bereitgestellt:
Direkt auf dem Host
FHEM (Freundliche Hausautomatisierung und Energiemessung)
HomeBridge (Schnittstelle FHEM zu AppleHomeKit)
Dockercontainer auf dem Host
MySQL DB (Logging für FHEM)
iobroker (JavaScript Umgebung zur Scriptausführung/steuerung im Energieumfeld)
scrypted (Einbindung klassischer WebCams in HomeKIT Umgebung)
piHole (Netzwerkfilterung)
zigbee2MQTT (Zigbee MQTT Schnittstelle zur Einbindung von Zigbee basierten Geräte mit dem MQTT Protokoll)
Insbesondere im Hinblick auf scrypted ist ein wenig Vorsicht geboten. Scrypted bedient sich, je nach der hardwareseitigen Beschaffenheit des Hostsystems, großzügig an den bereitgestellten Ressourcen. Scrypted dient der Einbindung von klassischen WebCams in das Heimnetz und der direkten Integration in die Apple HomeKIT Umgebung. Hier werden also Video- und Audiodaten verarbeitet, was den Host schon herausfordern kann.
Grundsätzlich rate ich in diesem Zusammenhang davon ab, einfach irgendwelche docker-compose Dateien aus dem Netz ungesichtet und „mal eben schnell“ bereitzustellen. Nicht gerade wenige Beispiele setzen neben dem eigentlichen Containerdienst auf den Einsatz eines sog. WatchTower Containers.
Ein WatchTower dient der Aktualisierung von Containern. Dieser macht im Grunde nichts anderes, als in regelmäßigen Abständen auf das Vorhandensein von Updates (Images) zu prüfen und diese automatisiert zu installieren/zu aktualisieren. Das kann je nach Umfang des Updates schnell das System zum Erliegen bringen, da der Ressourcenbedarf unverhältnismäßig angewachsen ist.
Docker-Compose -> Ressourcen fest zuweisen
Wie eingangs bereits erwähnt, sollte man insbesondere die Ressourcen RAM und CPU pro Container im Auge haben.
Über das entsprechende Docker run statement oder compose-file lassen sich die jeweiligen Ressourcen pro Container komfortabel steuern.
CPU, RAM, Swap und PIDs
Je nach Anforderung des Microservice (Containers) sollte die CPU eingeschränkt bzw. begrenzt werden.
Dieses erfolgt initial über den Parameter cpus (Version des Compose beachten!)
Ressourcen-Limits (Beispiel piHole)
cpus: 0.25
mem_limit: 512m
memswap_limit: 512m
pids_limit: 256
Beschreibung/Bedeutung:
cpus: 0.25
Der Container darf nur 25 % einer CPU nutzen (also ein Viertel eines Kerns). Wenn der Host mehrere CPUs hat, entspricht das rechnerisch 0,25 von allen verfügbaren Cores. Praktisch bedeutet es: der Container kann maximal 250 ms pro Sekunde auf einem Core rechnen.
mem_limit: 512m
Der Container darf maximal 512 MB Arbeitsspeicher nutzen. Wenn er mehr benötigt, wird er vom Kernel (OOM-Killer) beendet.
memswap_limit: 512m
Maximal nutzbarer Speicher inklusive Swap = 512 MB. Da hier mem_limit und memswap_limit gleich sind, hat der Container keinen zusätzlichen Swap zur Verfügung – er kann also effektiv nur 512 MB RAM nutzen.
(Wenn memswap_limit größer wäre als mem_limit, könnte er den Unterschied als Swap nutzen.)
pids_limit: 256
Maximal 256 Prozesse/Threads dürfen innerhalb des Containers gleichzeitig laufen. Damit wird verhindert, dass ein Container das System mit zu vielen Prozessen überlastet.
Alleine mit diesen Einstellungen/Konfiguationsparametern kann man eine Menge erreichen und ein einzelner Dienst „raubt“ weiteren Containers und natürlich auch dem Host selbst nicht alle verfügbaren Ressourcen.
Ressourcen-Limits (Beispiel scrypted)
CPU: insgesamt 1 Kern, aber über alle Cores verteilbar
cpus: 1.0
cpuset: "2"
cpu_shares: 256
mem_limit: 2g
memswap_limit: 2g
pids_limit: 512
CPU-Einstellungen
cpus: 1.0
Der Container darf maximal 1 ganze CPU nutzen (also 100 % eines Kerns).
→ Begrenzung auf eine CPU-Einheit, unabhängig davon, wie viele Kerne das Hostsystem hat.
cpuset: "2"
Der Container darf nur auf Core Nr. 2 laufen (die Zählung beginnt bei 0).
→ Beispiel: Auf einem 4-Kern-System (0,1,2,3) läuft dieser Container nur auf Kern 2.
Das ist eine Art CPU-Pinning.
cpu_shares: 256
Relatives Gewicht im Vergleich zu anderen Containern, wenn CPU-Ressourcen knapp sind.
Default-Wert ist 1024.
Speicher-Einstellungen
mem_limit: 2g
Maximal 2 GB RAM nutzbar. Wenn der Container mehr braucht, wird er beendet (OOM-Killer).
memswap_limit: 2g
Maximal nutzbarer Speicher inkl. Swap = 2 GB.
Da memswap_limit == mem_limit, heißt das: kein zusätzlicher Swap erlaubt, effektiv nur 2 GB RAM.
Prozess-Limit
pids_limit: 512
Maximal 512 Prozesse/Threads gleichzeitig im Container erlaubt.
→ Schutz vor Fork-Bomben oder übermäßiger Thread-Erzeugung.
Prüfen
Über den Befehl „docker stats“ kann man sich die aktuelle Ressourcenzuweisung der bereitgestellten Microservices anzeigen lassen:

Fazit
Ressourcenzuweisung/-beschränkung in Docker sorgt dafür, dass ein Container nicht mehr CPU, RAM oder Prozesse verbraucht als erlaubt.
👉 Vorteile:
- Stabilität: verhindert, dass ein Container das ganze System lahmlegt.
- Fairness: Ressourcen werden gerecht zwischen Containern verteilt.
- Planbarkeit: besseres Kapazitäts- und Performance-Management.
- Sicherheit: Schutz vor Fehlkonfigurationen oder Angriffen (z. B. Fork-Bombs).