Docker-Logrotation: Verhindern Sie, dass Logs Ihre VPS-Festplatte füllen

11 Min. Lesezeit·Matthieu·linuxdisk-managementloggingdocker-composedocker|

Dockers Standard-Logtreiber speichert unbegrenzt Daten. Ein einziger aktiver Container kann eine 50-GB-VPS-Festplatte in wenigen Tagen füllen. Diese Anleitung konfiguriert globale Logrotation, Compose-Überschreibungen pro Dienst, automatische Bereinigung und Speicherplatzüberwachung.

Dockers Standard-Logging-Konfiguration hat kein Größenlimit. Jede Zeile, die Ihre Container nach stdout oder stderr schreiben, wird dauerhaft auf der Festplatte gespeichert. Auf einem VPS mit 25 GB oder 50 GB Speicherplatz kann ein einziger gesprächiger Container den gesamten verfügbaren Platz in wenigen Tagen aufbrauchen.

Diese Anleitung behebt das Problem. Sie werden globale Logrotation konfigurieren, Limits pro Dienst in Docker Compose setzen, die Festplattenbereinigung automatisieren und eine Überwachung einrichten, damit das Problem Sie nie unvorbereitet trifft.

Alle Befehle sind auf Debian 12 und Ubuntu 24.04 mit Docker Engine 28.x/29.x getestet.

Voraussetzungen:

  • Ein VPS mit Debian 12 oder Ubuntu 24.04 und installiertem Docker
  • SSH-Zugang mit einem sudo-Benutzer
  • Grundkenntnisse in Docker und Docker Compose

Warum füllen Docker-Container-Logs Ihre Festplatte?

Dockers Standard-Logtreiber ist json-file. Er erfasst alles, was ein Container nach stdout und stderr schreibt, und speichert es als JSON unter /var/lib/docker/containers/<container-id>/<container-id>-json.log. Standardmäßig gibt es keine Maximalgröße und keine Rotation. Die Datei wächst, bis die Festplatte voll ist.

Eine Node.js-Anwendung, die auf INFO-Level loggt, produziert etwa 50 MB pro Tag. Ein Reverse Proxy unter mittlerer Last kann 200 MB oder mehr erzeugen. Auf einem 50-GB-VPS bedeutet das, dass ein einziger unkontrollierter Container den gesamten freien Speicherplatz innerhalb von Wochen verbrauchen kann.

Wenn die Festplatte voll ist, bricht alles gleichzeitig zusammen: Container können nicht mehr schreiben, Datenbanken stürzen ab, SSH-Sitzungen frieren ein und Sie können sich nicht einmal anmelden, um das Problem zu beheben.

Aktuelle Festplattennutzung prüfen

Bevor Sie etwas ändern, messen Sie den Schaden:

df -h /var/lib/docker

Das zeigt, wie viel Speicherplatz Dockers Datenverzeichnis belegt. Dann erhalten Sie eine Docker-spezifische Aufschlüsselung:

docker system df

Erwartete Ausgabe:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          5         3         1.2GB     450MB (37%)
Containers      8         4         3.8GB     3.1GB (81%)
Local Volumes   3         2         500MB     120MB (24%)
Build Cache     12        0         800MB     800MB (100%)

Die Zeile "Containers" zeigt die Größe der Logdateien. Wenn diese Zahl unverhältnismäßig groß ist, sind Logs das Problem.

Für eine Aufschlüsselung pro Container:

docker system df -v

Das listet jeden Container mit seiner Loggröße auf. Finden Sie die Verursacher.

Die größten Logdateien direkt finden

Wenn docker system df das Problem bestätigt, finden Sie heraus, welche Logs den Speicherplatz belegen:

sudo find /var/lib/docker/containers/ -name "*-json.log" -exec ls -sh {} + | sort -rh | head -10

Das listet die 10 größten Container-Logdateien mit ihren Größen auf.

Sofortmaßnahme: Speicherplatz jetzt freigeben

Wenn Ihre Festplatte bereits voll oder fast voll ist, beheben Sie zuerst das akute Problem, bevor Sie die Rotation konfigurieren.

Logdatei eines bestimmten Containers abschneiden (ohne den Container zu stoppen):

sudo truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log

Ersetzen Sie <container-id> durch die tatsächliche Container-ID aus docker ps --no-trunc -q.

Um alle Docker-Logdateien auf einmal abzuschneiden:

sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'

Überprüfen Sie, ob der Speicherplatz freigegeben wurde:

df -h /var/lib/docker

Das ist eine temporäre Lösung. Die Logs wachsen wieder an. Die folgenden Abschnitte machen die Lösung dauerhaft.

Wie konfigurieren Sie die Logrotation in der Docker daemon.json?

Die Datei daemon.json setzt Standard-Logging-Optionen für alle neuen Container. Dockers json-file-Treiber unterstützt max-size (maximale Größe pro Logdatei vor der Rotation) und max-file (Anzahl der rotierten Dateien, die aufbewahrt werden). Alle Werte in log-opts müssen Strings sein, auch Zahlen.

Erstellen oder bearbeiten Sie die Daemon-Konfiguration:

sudo nano /etc/docker/daemon.json

Wenn die Datei nicht existiert, erstellen Sie sie. Wenn sie bereits Konfiguration enthält (z. B. eigene Registries oder DNS), fügen Sie die Schlüssel log-driver und log-opts neben den bestehenden hinzu.

Größenempfehlungen nach VPS-Festplattengröße

Wählen Sie Werte basierend auf Ihrer VPS-Festplattengröße:

VPS-Festplattengröße max-size max-file Max. Log pro Container Begründung
25 GB 5m 3 15 MB Wenig Speicher; Logs minimal halten
50 GB 10m 5 50 MB Standard-VPS; ausgewogene Aufbewahrung
100 GB 25m 5 125 MB Großzügiger Speicher; längere Aufbewahrung
200 GB+ 50m 5 250 MB Großer Speicher; erweiterte Fehlersuche

Für einen 50-GB-VPS (die häufigste Wahl) verwenden Sie diese Konfiguration:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}

Speichern Sie die Datei und starten Sie Docker neu:

sudo systemctl restart docker

Überprüfen Sie, ob die neuen Standardwerte aktiv sind:

docker info --format '{{.LoggingDriver}}'

Erwartete Ausgabe:

json-file

Bestätigen Sie, dass die Log-Optionen auf neue Container angewendet werden, indem Sie einen starten und inspizieren:

docker run -d --name log-test alpine echo "test" && docker inspect --format '{{.HostConfig.LogConfig}}' log-test && docker rm log-test

Erwartete Ausgabe:

{json-file map[max-file:5 max-size:10m]}

Was passiert mit laufenden Containern nach der Änderung von daemon.json?

Bestehende Container behalten ihre ursprüngliche Log-Konfiguration. Die neuen Einstellungen gelten nur für Container, die nach dem Neustart erstellt werden. Laufende Container müssen neu erstellt werden, um die neuen Standardwerte zu übernehmen.

Wenn Sie Docker Compose verwenden:

docker compose down && docker compose up -d

Für eigenständige Container stoppen und entfernen Sie sie, dann starten Sie sie neu. Das Flag --force-recreate funktioniert ebenfalls:

docker compose up -d --force-recreate

Überprüfen Sie, ob ein bestimmter Container die neue Konfiguration verwendet:

docker inspect --format '{{.HostConfig.LogConfig}}' <container-name>

Erwartete Ausgabe:

{json-file map[max-file:5 max-size:10m]}

Wie setzen Sie Log-Limits in Docker Compose?

Die Log-Konfiguration pro Dienst in Docker Compose überschreibt die Standardwerte aus daemon.json. So können Sie gesprächigen Diensten engere Limits geben und ruhigen Diensten mehr Spielraum lassen.

Fügen Sie den logging-Block unter einem beliebigen Dienst hinzu:

services:
  web:
    image: nginx:alpine
    logging:
      driver: json-file
      options:
        max-size: "5m"
        max-file: "3"
    ports:
      - "80:80"

  api:
    image: node:22-alpine
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "5"
    ports:
      - "3000:3000"

Um den Logging-Block nicht in jedem Dienst wiederholen zu müssen, verwenden Sie einen YAML-Anker (Anchor):

x-logging: &default-logging
  logging:
    driver: json-file
    options:
      max-size: "10m"
      max-file: "5"

services:
  web:
    image: nginx:alpine
    <<: *default-logging
    ports:
      - "80:80"

  api:
    image: node:22-alpine
    <<: *default-logging
    ports:
      - "3000:3000"

  worker:
    image: myapp/worker:latest
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

Der Worker-Dienst überschreibt den Anker mit eigenen Limits. Alle anderen Dienste erhalten die gemeinsame Konfiguration.

Wenden Sie die Konfiguration an:

docker compose up -d --force-recreate

Kontrolle:

docker inspect --format '{{.HostConfig.LogConfig}}' web

Was ist der Unterschied zwischen den Logtreibern json-file, local und journald?

Docker liefert drei Logtreiber mit, die Logs auf dem Host speichern. Jeder hat andere Kompromisse. Der json-file-Treiber ist der Standard. Der local-Treiber ist Dockers empfohlener Ersatz für Speichereffizienz. Der journald-Treiber integriert sich in systemds Journal.

Eigenschaft json-file local journald
Standardrotation Keine Ja (100 MB gesamt) Verwaltet durch journald
Kompression Optional (compress: "true") Standardmäßig aktiv Verwaltet durch journald
docker logs-Unterstützung Ja Ja Ja
Logformat JSON (menschenlesbar) Binär (intern) Binär (journald)
Zugriff durch externe Tools Einfach (Klartextdateien) Nicht unterstützt Über journalctl
Standard-max-size Unbegrenzt 20 MB pro Datei In journald.conf festgelegt
Standard-max-file 1 (keine Rotation) 5 Dateien N/A

Wann welchen Treiber verwenden?

json-file ist der sichere Standard. Er funktioniert überall, unterstützt docker logs und die Logdateien sind einfaches JSON, das jedes Tool parsen kann. Fügen Sie max-size und max-file hinzu und er funktioniert gut für die meisten VPS-Setups.

local ist besser für Speichereffizienz. Kompression ist standardmäßig aktiv, Rotation ist eingebaut (5 Dateien zu je 20 MB = 100 MB pro Container) und Sie müssen nichts konfigurieren. Der Kompromiss: Logdateien verwenden ein internes Binärformat. Externe Log-Shipper, die Dateien direkt lesen (wie Filebeat im Dateimodus), können sie nicht parsen. Wenn Sie Logs nur über docker logs lesen oder sie über ein Docker-Logging-Plugin versenden, wechseln Sie zu local.

journald ist die richtige Wahl, wenn Sie bereits systemds Journal für alle anderen Dienste verwenden und Container-Logs am selben Ort haben möchten. Die Rotation wird durch journalds eigene Konfiguration (/etc/systemd/journald.conf) gesteuert. Sie lesen Logs mit journalctl statt docker logs (obwohl docker logs weiterhin funktioniert).

Zum local-Treiber wechseln

Bearbeiten Sie /etc/docker/daemon.json:

{
  "log-driver": "local",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}

Docker neu starten:

sudo systemctl restart docker

Überprüfen:

docker info --format '{{.LoggingDriver}}'

Erwartete Ausgabe:

local

Container neu erstellen, um den neuen Treiber anzuwenden:

docker compose up -d --force-recreate

Den journald-Treiber verwenden

Bearbeiten Sie /etc/docker/daemon.json:

{
  "log-driver": "journald"
}

Docker neu starten:

sudo systemctl restart docker

Logs eines bestimmten Containers lesen:

sudo journalctl CONTAINER_NAME=mycontainer --no-pager -n 50

Logs in Echtzeit verfolgen:

sudo journalctl CONTAINER_NAME=mycontainer -f

Die journald-Rotation wird in /etc/systemd/journald.conf gesteuert. Wichtige Einstellungen:

[Journal]
SystemMaxUse=500M
SystemMaxFileSize=50M
MaxRetentionSec=7day

Nach der Bearbeitung starten Sie journald neu:

sudo systemctl restart systemd-journald

Wie automatisieren Sie die Docker-Bereinigung mit cron oder systemd-Timern?

Logrotation verhindert, dass einzelne Container unbegrenzt wachsen. Aber Docker sammelt auch gestoppte Container, ungenutzte Images, verwaisten Build-Cache und verwaiste Netzwerke an. docker system prune räumt diese auf.

Was löscht docker system prune tatsächlich?

Standardmäßig entfernt docker system prune:

  • Alle gestoppten Container
  • Alle Netzwerke, die von keinem laufenden Container verwendet werden
  • Alle verwaisten Images (Dangling Images: ungetaggte Images, die von keinem Container referenziert werden)
  • Allen ungenutzten Build-Cache

Es löscht nicht:

  • Laufende Container
  • Benannte Volumes (Ihre Datenbankdaten sind sicher)
  • Getaggte Images, die noch referenziert werden
  • Images, die von laufenden Containern verwendet werden

Das Flag --all entfernt zusätzlich alle ungenutzten Images (nicht nur verwaiste). Das Flag --volumes nimmt anonyme Volumes in die Bereinigung auf. Verwenden Sie --volumes mit Vorsicht: Es zerstört Daten in anonymen Volumes.

Option 1: Cronjob

Erstellen Sie einen wöchentlichen Bereinigungsjob:

sudo crontab -e

Fügen Sie hinzu:

0 3 * * 0 /usr/bin/docker system prune -f >> /var/log/docker-prune.log 2>&1

Das läuft jeden Sonntag um 03:00 Uhr. Das Flag -f überspringt die Bestätigungsaufforderung. Die Ausgabe wird in eine Logdatei geschrieben.

Überprüfen Sie, ob der Crontab gespeichert wurde:

sudo crontab -l

Option 2: systemd-Timer (empfohlen)

Systemd-Timer sind zuverlässiger als Cron. Sie loggen ins Journal, behandeln verpasste Ausführungen (wenn der Server ausgeschaltet war) und sind einfacher zu überwachen.

Erstellen Sie die Service-Unit:

sudo nano /etc/systemd/system/docker-prune.service
[Unit]
Description=Docker system prune
Wants=docker.service
After=docker.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker system prune -f --filter "until=168h"

Das Flag --filter "until=168h" bereinigt nur Objekte, die älter als 7 Tage sind. Das schützt kürzlich gestoppte Container, die Sie möglicherweise noch untersuchen möchten.

Erstellen Sie den Timer:

sudo nano /etc/systemd/system/docker-prune.timer
[Unit]
Description=Run Docker prune weekly

[Timer]
OnCalendar=Sun *-*-* 03:00:00
Persistent=true
RandomizedDelaySec=1800

[Install]
WantedBy=timers.target

Persistent=true bedeutet: Wenn der Server zur geplanten Zeit ausgeschaltet war, wird der Job beim nächsten Start ausgeführt. RandomizedDelaySec verteilt die Last, wenn Sie mehrere Server betreiben.

Aktivieren und starten Sie den Timer:

sudo systemctl daemon-reload
sudo systemctl enable --now docker-prune.timer

enable sorgt dafür, dass er Neustarts überlebt. --now startet ihn sofort.

Überprüfen Sie, ob der Timer aktiv ist:

sudo systemctl status docker-prune.timer

Prüfen Sie, wann er als Nächstes ausgeführt wird:

sudo systemctl list-timers docker-prune.timer

Testen Sie ihn manuell:

sudo systemctl start docker-prune.service

Prüfen Sie das Ergebnis:

sudo journalctl -u docker-prune.service --no-pager -n 20

Wie bereinigen Sie Docker-Volumes sicher?

Volumes enthalten persistente Daten: Datenbanken, Uploads, Konfigurationen. Gehen Sie hier vorsichtig vor.

Alle Volumes und ihre Nutzung auflisten:

docker volume ls

Nur Volumes anzeigen, die an keinen Container gebunden sind:

docker volume ls -f dangling=true

Verwaiste Volumes entfernen:

docker volume prune -f

Das entfernt nur Volumes, die aktuell von keinem Container (laufend oder gestoppt) verwendet werden. Benannte Volumes, die an gestoppte Container gebunden sind, bleiben erhalten.

Überprüfen Sie, was übrig bleibt:

docker volume ls

Führen Sie niemals docker volume prune direkt nach docker system prune --volumes aus. Das system prune mit --volumes erledigt die Volume-Bereinigung bereits. Beides auszuführen ist bestenfalls überflüssig.

Um ein bestimmtes Volume zu entfernen, das Sie als unnötig identifiziert haben:

docker volume rm <volume-name>

Prüfen Sie immer, welche Daten ein Volume enthält, bevor Sie es entfernen:

docker volume inspect <volume-name>

Das Feld Mountpoint zeigt, wo die Daten auf der Festplatte liegen. Sie können den Inhalt untersuchen:

sudo ls -la $(docker volume inspect --format '{{.Mountpoint}}' <volume-name>)

Wie überwachen Sie die Docker-Festplattennutzung auf einem VPS?

Automatisierte Überwachung verhindert Überraschungen. Dieser Abschnitt richtet einen Schwellenwert-Alarm ein, der die Docker-Festplattennutzung prüft und eine Warnung sendet, wenn ein Limit überschritten wird.

Schnelle manuelle Prüfung

Führen Sie diese beiden Befehle aus, wenn Sie eine Momentaufnahme möchten:

df -h /var/lib/docker
docker system df

Für eine detaillierte Aufschlüsselung pro Container und pro Image:

docker system df -v

Automatisches Alarmskript

Erstellen Sie ein Überwachungsskript:

sudo nano /usr/local/bin/docker-disk-alert.sh
#!/bin/bash
# Alert when Docker's partition exceeds a usage threshold
THRESHOLD=80
MAILTO="admin@example.com"

USAGE=$(df /var/lib/docker | awk 'NR==2 {gsub(/%/,""); print $5}')

if [ "$USAGE" -ge "$THRESHOLD" ]; then
    DOCKER_DF=$(docker system df 2>&1)
    DISK_DF=$(df -h /var/lib/docker 2>&1)
    TOP_LOGS=$(find /var/lib/docker/containers/ -name "*-json.log" -exec ls -sh {} + 2>/dev/null | sort -rh | head -5)

    BODY="Docker disk usage on $(hostname) is at ${USAGE}%.

Disk usage:
${DISK_DF}

Docker breakdown:
${DOCKER_DF}

Largest log files:
${TOP_LOGS}"

    echo "$BODY" | mail -s "ALERT: Docker disk at ${USAGE}% on $(hostname)" "$MAILTO"
    logger -t docker-disk-alert "Docker disk usage at ${USAGE}% - alert sent"
fi

Berechtigungen setzen:

sudo chmod 750 /usr/local/bin/docker-disk-alert.sh

Berechtigungen überprüfen:

ls -la /usr/local/bin/docker-disk-alert.sh

Erwartete Ausgabe:

-rwxr-x--- 1 root root 612 Mar 19 12:00 /usr/local/bin/docker-disk-alert.sh

Das Skript benötigt mailutils (oder mailx) für den E-Mail-Versand. Installieren Sie es, falls nicht vorhanden:

sudo apt install -y mailutils

Testen Sie das Skript:

sudo /usr/local/bin/docker-disk-alert.sh

Wenn Ihre Festplattennutzung unter dem Schwellenwert liegt, passiert nichts. Um den Alarmpfad zu testen, setzen Sie THRESHOLD=1 vorübergehend im Skript, führen Sie es aus und setzen Sie den Wert dann zurück.

Alarm mit einem systemd-Timer planen

Erstellen Sie den Service:

sudo nano /etc/systemd/system/docker-disk-alert.service
[Unit]
Description=Check Docker disk usage

[Service]
Type=oneshot
ExecStart=/usr/local/bin/docker-disk-alert.sh

Erstellen Sie den Timer:

sudo nano /etc/systemd/system/docker-disk-alert.timer
[Unit]
Description=Check Docker disk usage every 6 hours

[Timer]
OnCalendar=*-*-* 00/6:00:00
Persistent=true

[Install]
WantedBy=timers.target

Aktivieren Sie ihn:

sudo systemctl daemon-reload
sudo systemctl enable --now docker-disk-alert.timer

Überprüfen:

sudo systemctl list-timers docker-disk-alert.timer

Fehlerbehebung

Festplatte ist voll und Docker startet nicht

Wenn Docker den Start verweigert, weil die Festplatte komplett voll ist:

sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
sudo systemctl start docker

Konfigurieren Sie dann sofort die Logrotation wie oben beschrieben.

Syntaxfehler in daemon.json verhindert den Docker-Start

Docker startet nicht, wenn daemon.json ungültiges JSON enthält. Validieren Sie die Datei:

sudo python3 -m json.tool /etc/docker/daemon.json

Wenn das formatierte JSON ausgegeben wird, ist die Syntax korrekt. Wenn ein Fehler angezeigt wird, korrigieren Sie die angegebene Zeile.

Prüfen Sie Dockers Fehlermeldung:

sudo journalctl -u docker.service -n 20 --no-pager

Logs wachsen trotz konfigurierter Rotation weiter

Die Rotation gilt nur für neue Container. Bestehende Container behalten ihre ursprüngliche Konfiguration. Erstellen Sie sie neu:

docker compose up -d --force-recreate

Überprüfen Sie, ob die neue Konfiguration wirksam ist:

docker inspect --format '{{.HostConfig.LogConfig}}' <container-name>

docker system prune hat nicht viel Speicherplatz freigegeben

docker system prune berührt keine laufenden Container, deren Logs oder benannte Volumes. Wenn das Speicherproblem speziell Logs betrifft, schneiden Sie die Logdateien ab oder konfigurieren Sie die Rotation. Wenn es Volumes betrifft, verwenden Sie docker volume prune, nachdem Sie sichergestellt haben, dass keine benötigten Daten verloren gehen.

Prüfen Sie, was den Speicherplatz belegt:

sudo du -sh /var/lib/docker/*

Das schlüsselt die Nutzung nach Docker-Subsystem auf: containers (Logs), overlay2 (Images/Layer), volumes und andere.

Zusammenfassung

Ein vollständiges Docker-Log-Management-Setup auf einem VPS hat vier Ebenen:

  1. Globale Rotation in /etc/docker/daemon.json mit max-size und max-file verhindert unbegrenztes Log-Wachstum für alle Container.
  2. Überschreibungen pro Dienst in Docker Compose geben gesprächigen Diensten engere Limits.
  3. Automatische Bereinigung mit docker system prune über einen systemd-Timer entfernt tote Container, ungenutzte Images und Build-Cache.
  4. Festplattenüberwachung mit einem Alarmskript erkennt Probleme, bevor sie zu Ausfällen werden.

Nach der Einrichtung überprüfen Sie das Ergebnis: Kontrollieren Sie docker inspect bei Ihren Containern, führen Sie docker system df aus, um die aktuelle Nutzung zu bestätigen, und warten Sie, bis der Prune-Timer mindestens einmal ausgelöst hat. Prüfen Sie journalctl -u docker-prune.service, um die Ausführung zu bestätigen.


Copyright 2026 Virtua.Cloud. Alle Rechte vorbehalten. Dieser Inhalt ist ein Originalwerk des Virtua.Cloud-Teams. Vervielfältigung, Wiederveröffentlichung oder Weiterverbreitung ohne schriftliche Genehmigung ist untersagt.

Bereit, es selbst auszuprobieren?

Halten Sie Ihren Docker-VPS mit Log-Rotation sauber.

VPS-Angebote ansehen