raatools/

Docker RAM Planer

Container-Speichernutzung gegen verfügbaren RAM planen.

Container hinzufügen

Services

Custom

RAM Usage 12.5%

Gesamt-RAM verwendet

0 MB

Verbleibend

3584 MB

Systemreserviert

512 MB

Fits comfortably

Good headroom for scaling and memory spikes.

Was ist ein Docker-RAM-Rechner?

Ein Docker-RAM-Rechner schaetzt den Arbeitsspeicherbedarf Ihrer Docker-Container und hilft bei der Planung der Serverressourcen. Richtige Speicherzuweisung verhindert Abstuerze und OOM-Kills (Out of Memory).

Docker-Container teilen sich den Kernel des Hostsystems, benoetigen aber jeweils eigenen RAM fuer ihre Prozesse. Die Summe des Container-RAM-Bedarfs plus Betriebssystem-Overhead bestimmt die benoetigte Server-RAM-Groesse.

So verwenden Sie dieses Tool

Waehlen Sie die Services aus, die Sie ausfuehren moechten (Datenbanken, Webserver, Caches usw.), oder geben Sie benutzerdefinierte Container mit ihrem erwarteten RAM-Bedarf ein. Das Tool berechnet den Gesamtbedarf mit Sicherheitspuffer.

Arbeitsspeicher-Limits vs. Arbeitsspeicher-Reservierungen

Docker bietet zwei separate Einstellungen, um den RAM-Verbrauch eines Containers zu steuern: Arbeitsspeicher-Limits und Arbeitsspeicher-Reservierungen. Sie werden oft verwechselt, dienen aber völlig unterschiedlichen Zwecken.

Ein Arbeitsspeicher-Limit (festgelegt mit --memory oder mem_limit in einer Compose-Datei) ist eine harte Obergrenze. Docker setzt es über das Linux-Subsystem für Kontrollgruppen (cgroups) durch. Der Container kann niemals mehr als diesen Betrag anfordern – versucht er es dennoch, greift der Linux-Kernel-OOM-Killer ein.

  • --memory / mem_limit: die harte Obergrenze. Der Container darf diesen Wert nicht überschreiten. Schützt den Host vor außer Kontrolle geratenen Prozessen.
  • --memory-reservation / mem_reservation: ein weicher Hinweis für den Scheduler. Der Swarm-Scheduler von Docker verwendet diesen Wert, um zu entscheiden, wo Dienste platziert werden. Er verhindert NICHT, dass der Container mehr verbraucht – er ist lediglich eine Mindestgarantie, die Docker zu erfüllen versucht.
  • Eine gängige Best Practice: Setzen Sie die Reservierung auf den erwarteten Leerlauf-Fußabdruck und das Limit auf das Maximum, das Sie zulassen möchten. Ein Container, der im Leerlauf 200 MB benötigt, aber auf bis zu 600 MB ansteigen kann, könnte zum Beispiel mit reservation=200m und limit=600m konfiguriert werden.

Werden beide Flags weggelassen, hat der Container kein Limit und kann den gesamten verfügbaren Host-RAM verbrauchen. Auf einem Einzelzweck-Server mag das akzeptabel sein, auf einem Homelab mit vielen Diensten ist es jedoch ein erhebliches Risiko.

Was passiert, wenn ein Container sein Arbeitsspeicher-Limit erreicht

Wenn der Arbeitsspeicherverbrauch eines Containers den mit --memory festgelegten Wert erreicht, beendet der Linux-Kernel-OOM-Killer (Out of Memory) den arbeitsspeicherintensivsten Prozess im Container. Docker protokolliert dies als Exit-Code 137 – eine standardmäßige POSIX-Signal-9-(SIGKILL)-Beendigung. In docker ps --all oder den Container-Logs erscheint dies als „Exited (137)”.

Exit-Code 137 bedeutet nicht, dass Ihre Anwendung wegen eines Fehlers abgestürzt ist – der Kernel hat sie zwangsweise beendet, weil der Container die von Ihnen konfigurierte RAM-Obergrenze erreicht hat. Wenn Sie bei einer stabilen Anwendung wiederholt 137-Exits beobachten, ist Ihr Arbeitsspeicher-Limit zu niedrig oder die Arbeitslast ist über die ursprüngliche Schätzung hinausgewachsen. Erhöhen Sie das Limit und überwachen Sie erneut mit docker stats.

Laufzeitspezifische Arbeitsspeicher-Überlegungen

Verschiedene Sprachlaufzeiten und Datenbank-Engines verwalten den Arbeitsspeicher sehr unterschiedlich. Ein Container-Arbeitsspeicher-Limit festzulegen, ohne das Laufzeitverhalten zu berücksichtigen, ist eine der häufigsten Ursachen für unerwartete OOM-Kills.

  • JVM (Java, Kotlin, Scala): die JVM reserviert einen Heap vorab. Ohne explizite Flags kann sie beim Start einen großen Teil des verfügbaren System-RAMs beanspruchen. Setzen Sie -Xmx (maximaler Heap) immer auf einen Wert unterhalb Ihres Docker-Arbeitsspeicher-Limits – eine gängige Richtlinie ist es, mindestens 25 % Puffer über -Xmx für Off-Heap-Speicher, Garbage-Collection-Overhead und native Bibliotheken einzuplanen.
  • Node.js: V8 hat ein Standard-Heap-Limit (ca. 1,5 GB auf 64-Bit-Systemen in älteren Versionen). Ist Ihr Docker-Limit niedriger, kann der Prozess per OOM-Kill beendet werden, bevor V8 überhaupt die Garbage Collection auslöst. Verwenden Sie --max-old-space-size (in MB), um den V8-Old-Generation-Heap zu begrenzen, und setzen Sie ihn unterhalb des Docker-Arbeitsspeicher-Limits.
  • Datenbanken (PostgreSQL, MariaDB, MySQL): Datenbanken sind von Natur aus speicherhungrig – sie cachen häufig abgerufene Seiten in ihrem gemeinsamen Puffer-Pool. Der shared_buffers-Standardwert von PostgreSQL beträgt 128 MB, wird aber typischerweise auf 25 % des verfügbaren RAMs für dedizierte Server eingestellt. Stimmen Sie shared_buffers innerhalb eines Containers so ab, dass es in Ihr Arbeitsspeicher-Limit passt, sonst wird die Datenbank unter Last unerwartet beendet.
  • Media-Server (Jellyfin, Plex): Transkodierung ist sehr arbeitsspeicherintensiv. Eine einzelne 4K-Transkodierung kann zusätzlich zum Leerlauf-Fußabdruck 1–3 GB erfordern. Wenn Sie hardware-beschleunigte Transkodierung aktivieren, ändert sich das Arbeitsspeicherbild erheblich. Überprüfen Sie die tatsächliche Auslastung Ihres Servers unter echter Last, bevor Sie die Limits finalisieren.

Typischer RAM-Bedarf gaengiger Services

Die nachstehenden Werte sind grobe Ausgangsbereiche nur zur Planungszwecken – der tatsächliche Verbrauch variiert je nach Konfiguration, Datensatzgröße, Anzahl der Nutzer und aktivierten Funktionen erheblich. Messen Sie immer mit docker stats, nachdem Sie Ihre tatsächliche Arbeitslast ausgeführt haben.

  • Nginx/Caddy — 50-100 MB. Leichtgewichtige Webserver/Reverse-Proxies mit minimalem Speicherbedarf.
  • Node.js-App — 100-500 MB. Abhaengig von der Anwendung und den geladenen Abhaengigkeiten.
  • PostgreSQL — 256 MB-2 GB. Abhaengig von shared_buffers und work_mem Konfiguration.
  • Redis — 50-500 MB. Abhaengig von der Datensatzgroesse, da Redis alles im RAM haelt.
  • Elasticsearch — 2-8 GB. Speicherintensiv, benoetigt mindestens 2 GB Heap.
  • Leichtgewichtige Reverse-Proxys (Traefik, Caddy, Nginx): generell 30–150 MB im Leerlauf; diese gehören zu den speichereffizientesten Diensten, die Sie betreiben können.
  • Monitoring-Stacks (Prometheus + Grafana): Prometheus skaliert mit der Anzahl der Zeit-Reihen, die es abfragt und aufbewahrt – von einigen hundert MB bis zu mehreren GB in großen Umgebungen. Grafana selbst ist mit ca. 100–300 MB vergleichsweise schlank.

Praxisbeispiel: ein typisches Homelab auf einem Raspberry Pi 4 (8 GB)

Um zu sehen, wie sich die RAM-Zuweisung summiert, betrachten Sie einen Raspberry Pi 4 mit 8 GB, der einen kleinen selbst gehosteten Stack betreibt:

  • Host-BS (Raspberry Pi OS Lite): ~300–500 MB reserviert für Kernel, Systemprozesse und die Docker-Engine selbst
  • Pi-hole (DNS-Werbeblocker): Limit 128 MB – leichtgewichtiger Dienst mit geringem Overhead
  • Vaultwarden (Bitwarden-kompatibler Passwort-Manager): Limit 128 MB – sehr schlankes Rust-Binary
  • Home Assistant: Limit 512 MB – Python-basiert, wächst mit Automationen und Integrationen
  • Jellyfin (Media-Server, Software-Transkodierung deaktiviert): Limit 1024 MB – skaliert mit der Bibliotheksgröße
  • Portainer (Container-Verwaltungsoberfläche): Limit 256 MB

Summe dieser Limits: 500 (Host) + 128 + 128 + 512 + 1024 + 256 = ca. 2,5 GB zugewiesen. Auf einem 8-GB-Gerät bleiben damit etwa 5,5 GB Puffer – ein komfortables Polster für Caching, Lastspitzen und zukünftige Container. Auf einem 2-GB-Pi 4 wäre derselbe Stack bereits überbucht, bevor auch nur Lastspitzen berücksichtigt werden. Der Rechner oben führt genau diese Art von Kalkulation für beliebige Kombinationen von Diensten durch.

Warum Überbuchen von RAM riskant ist

Überbuchen bedeutet, einen Stack zu planen, dessen kombinierte Arbeitsspeicher-Limits den physisch verfügbaren RAM des Host-Betriebssystems übersteigen. Docker selbst verhindert das nicht – es akzeptiert problemlos eine Compose-Datei, die 10 GB auf Container verteilt, obwohl die Maschine nur 4 GB hat. Das Risiko tritt zur Laufzeit auf: Wenn die tatsächliche Auslastung aller Container den physischen RAM annähert, beginnt der Kernel aggressiv zu swappen. Swap auf SD-Karten und USB-Laufwerken (üblicher Homelab-Speicher) ist um Größenordnungen langsamer als RAM und kann systemweite Einfrierungen verursachen.

Das Host-Betriebssystem selbst benötigt ebenfalls Freiraum jenseits des Container-Verbrauchs. Der Linux-Page-Cache, Kernel-Puffer und Systemdienste konkurrieren alle um RAM. Als Faustregel gilt: Planen Sie niemals einen Stack, der nach der Summe der Container-Limits weniger als 10–15 % des gesamten RAMs für den Host frei lässt. Auf einem 4-GB-Gerät bedeutet das, mindestens 400–600 MB unzugewiesen zu lassen.

Tipps zur Speicheroptimierung

Setzen Sie immer Speicherlimits fuer Container (--memory Flag oder mem_limit in docker-compose). Ohne Limits kann ein fehlerhafter Container den gesamten verfuegbaren RAM verbrauchen und andere Container zum Absturz bringen.

Häufige Fehler bei der Docker-RAM-Dimensionierung

  • Keine Limits setzen: ohne --memory-Limits kann jeder Container den gesamten Host-RAM verbrauchen und alle anderen Dienste auf der Maschine zum Absturz bringen.
  • Reservierung mit Limit verwechseln: eine hohe mem_reservation begrenzt den Verbrauch nicht – ein Container mit einer großen Reservierung und ohne Limit kann den Host-RAM trotzdem erschöpfen.
  • Host-BS-Overhead ignorieren: 100 % des physischen RAMs auf Container zu verteilen lässt nichts für Kernel, Docker-Engine und Hintergrundprozesse übrig.
  • Dimensionierung anhand der Image-Dokumentation statt der tatsächlichen Nutzung: offizielle Images geben oft Mindestanforderungen an. Der tatsächliche RSS unter Ihrer echten Arbeitslast kann 2–5× höher sein. Überprüfen Sie immer mit docker stats.
  • Laufzeit-Heap-Einstellungen vergessen: Container für JVM- oder Node-Anwendungen ohne festgelegtes Heap-Limit versuchen, so viel Arbeitsspeicher wie das Container-Limit erlaubt zu nutzen – oder überschreiten es und lösen einen OOM-Kill aus.

Haeufig gestellte Fragen

Was passiert bei einem OOM-Kill?

Wenn ein Container sein Speicherlimit ueberschreitet, beendet der Linux-Kernel den Prozess (OOM-Kill). Der Container wird mit Exit-Code 137 beendet. Pruefen Sie mit 'docker inspect' ob OOMKilled wahr ist.

Wie viel RAM sollte ich fuer das Betriebssystem reservieren?

Reservieren Sie 10-20 % des RAM fuer das Host-Betriebssystem und Docker-Overhead (mindestens 512 MB bis 1 GB). Bei Servern mit viel I/O sollten Sie mehr Puffer fuer den Dateisystem-Cache einplanen.

Sollte ich Swap für Docker-Container konfigurieren?

Docker ermöglicht es, ein Swap-Limit separat mit --memory-swap festzulegen. Wenn Sie --memory=512m und --memory-swap=1g setzen, erhält der Container 512 MB RAM plus 512 MB Swap. Swap bietet ein Sicherheitsnetz, das sofortige OOM-Kills verhindert, aber sich für den normalen Betrieb auf Swap zu verlassen beeinträchtigt die Performance erheblich – besonders auf Flash-Speicher. Verwenden Sie Swap als letzten Puffer, nicht als Ersatz für ausreichend RAM. Auf Systemen ohne explizites --memory-swap-Flag setzt Docker standardmäßig das Doppelte des Arbeitsspeicher-Limits als Swap.

Wie finde ich heraus, wie viel RAM meine laufenden Container tatsächlich verwenden?

Führen Sie docker stats aus, um eine Live-Ansicht von CPU, Arbeitsspeicherverbrauch und Arbeitsspeicher-Limits für jeden laufenden Container zu erhalten. Die Spalte MEM USAGE zeigt den aktuellen RSS (Resident Set Size) des Containers. Vergleichen Sie diesen Wert mit Ihren konfigurierten Limits, um zu sehen, wie viel Puffer jeder Container hat. Für eine einmalige Momentaufnahme verwenden Sie docker stats --no-stream. Sie können auch einen bestimmten Container mit docker inspect <name> untersuchen und nach dem Feld MemoryStats suchen.