Ein einziger außer Kontrolle geratener Container kann einen ganzen Server ausbremsen, wenn er sich unbegrenzt Arbeitsspeicher und CPU nimmt. Die Lösung sind Ressourcen-Limits. In dieser Anleitung zeigen wir dir, wie du Docker-Container in CPU und RAM begrenzt – per Kommandozeile und in der docker-compose.yml.
Standardmäßig darf sich ein Docker-Container so viel CPU und Arbeitsspeicher nehmen, wie das Host-System hergibt. Auf einem geteilten Server ist das ein Risiko: Ein einziger Speicher-Leak oder eine Endlosschleife kann alle anderen Dienste ausbremsen oder den Host zum Stillstand bringen. Mit Ressourcen-Limits ziehst du klare Grenzen und sorgst für vorhersehbaren Betrieb. In dieser Anleitung lernst du nicht nur die passenden Flags für docker run und die docker-compose.yml, sondern auch, wie CPU-Shares, der OOM-Killer und Reservierungen im Hintergrund funktionieren – damit deine Container-Limits im Ernstfall wirklich greifen.
- Warum Limits setzen?
- Limits bei docker run
- Limits in docker-compose.yml
- Ressourcenverbrauch beobachten
- Häufige Fehler
- CPU-Limits richtig verstehen
- RAM-Limits und der OOM-Killer
- Limits für die Produktion planen
- Häufige Fragen
- Was passiert, wenn ein Container sein RAM-Limit überschreitet?
- Was ist der Unterschied zwischen Limit und Reservation?
- Warum scheint meine CPU-Begrenzung ignoriert zu werden?
- Fazit
Warum Limits setzen?
Standardmäßig dürfen Container so viele Ressourcen nutzen, wie der Host hergibt. Ein Speicherleck oder ein Lastspitze reicht dann, um andere Dienste zu verdrängen. Limits schaffen faire Verhältnisse und schützen den Host.
Limits bei docker run
Über --memory und --cpus begrenzt du einen Container direkt beim Start:
docker run -d \
--memory="512m" \
--cpus="1.5" \
--name app meine-app:latestDas erlaubt maximal 512 MB RAM und 1,5 CPU-Kerne. Überschreitet der Container das Speicherlimit, beendet Docker ihn (OOM-Kill).
Limits in docker-compose.yml
In Compose setzt du Limits über den deploy.resources-Block. Das funktioniert auch ohne Swarm:
services:
app:
image: meine-app:latest
deploy:
resources:
limits:
cpus: "1.5"
memory: 512M
reservations:
memory: 256Mlimits ist die Obergrenze, reservations reserviert ein Minimum. Die Grundlagen liefert Docker Compose installieren.
Ressourcenverbrauch beobachten
Ob deine Limits passen, siehst du am Live-Verbrauch aller Container:
docker statsDie Ausgabe zeigt CPU- und Speichernutzung in Echtzeit – ideal, um Limits sinnvoll einzustellen. Für den Blick aufs Gesamtsystem hilft Speicherplatz analysieren.
Häufige Fehler
- Limit zu niedrig gesetzt: Erreicht ein Container sein Speicherlimit, beendet Docker ihn hart (Exit-Code 137, OOM-Kill). Beobachte den realen Bedarf, bevor du eng limitierst.
- CPU-Limit missverstanden:
--cpus="1.5"bedeutet 1,5 Kerne Rechenzeit, nicht „Kern 1 und 2″. Zum Anpinnen konkreter Kerne gibt es--cpuset-cpus. - Limits vergessen: Ohne Limit darf ein Container den gesamten Host beanspruchen – setze sie besonders bei öffentlich erreichbaren Diensten.
CPU-Limits richtig verstehen
Bei der CPU gibt es mehrere Stellschrauben, die leicht verwechselt werden. --cpus gibt eine harte Obergrenze an CPU-Zeit an – --cpus="1.5" bedeutet, der Container darf höchstens anderthalb Kerne auslasten. --cpu-shares dagegen ist nur eine relative Gewichtung, die erst greift, wenn tatsächlich Knappheit herrscht. Mit --cpuset-cpus bindest du einen Container fest an bestimmte Kerne.
| Option | Wirkung | Wann sinnvoll |
|---|---|---|
--cpus | Harte Obergrenze an CPU-Zeit | Klare Deckelung pro Dienst |
--cpu-shares | Relatives Gewicht bei Knappheit | Priorisierung mehrerer Container |
--cpuset-cpus | Bindung an bestimmte Kerne | Isolation, NUMA-Optimierung |
Für die meisten Setups ist --cpus die richtige Wahl, weil das Verhalten leicht vorhersagbar ist. --cpu-shares lohnt sich erst, wenn mehrere Container um dieselben Kerne konkurrieren und du festlegen willst, wer im Zweifel Vorrang bekommt. --cpuset-cpus schließlich ist ein Spezialwerkzeug: Es hält latenzkritische Dienste von anderer Rechenlast fern und kann auf Servern mit mehreren CPU-Sockeln Zugriffe über NUMA-Grenzen hinweg vermeiden.
RAM-Limits und der OOM-Killer
Setzt du mit --memory="512m" ein Speicherlimit und der Container überschreitet es, greift der OOM-Killer des Kernels ein und beendet den Prozess hart. Für die Anwendung fühlt sich das wie ein plötzlicher Absturz an. Deshalb solltest du das Limit an den realen Bedarf plus einen Puffer anlehnen und nicht zu knapp wählen.
Ein häufig übersehener Punkt ist Swap: Mit --memory-swap steuerst du, wie viel Auslagerungsspeicher zusätzlich erlaubt ist. Setzt du beide Werte gleich, verbietest du Swap komplett – oft die sauberste Variante, weil ein Dienst, der ins Swapping gerät, meist ohnehin unbrauchbar langsam wird. Beobachte den tatsächlichen Verbrauch am besten laufend, etwa mit top und htop.
Limits für die Produktion planen
Limits sind eine Obergrenze, Reservierungen dagegen eine Zusicherung. In Compose legst du mit deploy.resources.limits das Maximum fest und mit deploy.resources.reservations das Minimum, das der Scheduler garantiert freihält. In der Kombination bekommst du planbare Lasten, ohne Reserven zu verschenken.
- Miss zuerst, dann limitiere: Beobachte den Verbrauch unter realer Last, bevor du Werte festlegst.
- Puffer einplanen: Rund 20–30 Prozent über dem Spitzenbedarf verhindern unnötige OOM-Kills.
- Limits dokumentieren: Halte sie in der Compose-Datei fest, damit sie versioniert und reproduzierbar sind.
- Nach Updates neu prüfen: Neue Programmversionen ändern oft den Speicherbedarf.
Zum Feinjustieren ist docker stats dein bester Freund: Der Befehl zeigt live den CPU- und RAM-Verbrauch aller laufenden Container, jeweils samt Prozentwert im Verhältnis zum gesetzten Limit. Läuft ein Dienst dauerhaft nahe an seiner Speichergrenze, ist das ein klares Signal, das Limit anzuheben oder die Anwendung selbst zu optimieren. Umgekehrt zeigt dir eine dauerhaft niedrige Auslastung, dass du Reserven zu großzügig vergeben hast und Kapazität für andere Container frei wird.
Häufige Fragen
Rund um Ressourcen-Limits gibt es einige Missverständnisse. Die folgenden Antworten räumen die häufigsten aus.
Was passiert, wenn ein Container sein RAM-Limit überschreitet?
Der Kernel beendet den speicherhungrigsten Prozess im Container über den OOM-Killer. Der Container stoppt oder startet – je nach Restart-Policy – neu. In den Logs (dmesg oder journalctl) findest du einen entsprechenden „Out of memory“-Eintrag.
Was ist der Unterschied zwischen Limit und Reservation?
Ein Limit ist die Obergrenze, die ein Container nicht überschreiten darf. Eine Reservation ist die garantierte Mindestmenge, die ihm zugesichert wird. Limits schützen den Host, Reservierungen schützen den einzelnen Dienst vor Aushungern.
Warum scheint meine CPU-Begrenzung ignoriert zu werden?
Häufig wird --cpu-shares mit einer harten Grenze verwechselt: Shares wirken nur bei Konkurrenz um die CPU. Solange der Host nicht ausgelastet ist, darf der Container mehr nutzen. Für eine echte Deckelung brauchst du --cpus.
Fazit
Mit --memory/--cpus oder dem deploy.resources-Block hältst du einzelne Container im Zaum und schützt den ganzen Host vor Überlastung. Beobachte den Verbrauch mit docker stats und passe die Grenzen an. Zusammen mit Healthchecks und Restart-Policies läuft deine Umgebung stabil und vorhersehbar.

