truncate -s 0 "$(docker inspect --format '{{.LogPath}}' api)" leert das Log eines laufenden Containers und gibt den Platz sofort frei, ganz ohne Neustart. rm ist hier tabu: der Daemon schreibt weiter in die gelöschte Datei, der Platz kommt nicht zurück und docker logs bleibt kaputt, bis der Container neu startet.
1. Zuerst sehen, was Docker wirklich belegt
$ clai wie viel plattenplatz belegt docker→ docker system dfTYPE TOTAL ACTIVE SIZE RECLAIMABLEImages 48 14 28.88GB 20GB (69%)Containers 17 10 4.631MB 513.8kB (11%)Local Volumes 38 7 6.349GB 4.084GB (64%)Build Cache 181 0 0B 0B
Logs tauchen in dieser Tabelle gar nicht auf — die Zeile Containers zählt nur die Schreibschicht. Wenn df die Platte als voll meldet und docker system df ruhig bleibt, sind die Logs der Verdächtige.
2. Den Container finden, der am meisten schreibt
$ clai zeige die logdateigröße jedes containers, größte zuerst→ docker ps -q | xargs docker inspect --format '{{.LogPath}} {{.Name}}' | while read -r p n; do printf '%s\t%s\n' "$(du -h "$p" | cut -f1)" "${n#/}"; done | LC_ALL=C sort -rh | head -36.1M api3.2M worker1.9M cache
LogPath ist der einzige verlässliche Weg zur Datei: bei rootful und rootless Installationen liegt sie woanders. LC_ALL=C ist keine Zierde — in einer Locale mit Komma als Dezimaltrenner stellt sort -h 844K über 6.1M.
3. Das Log eines laufenden Containers kürzen
$ clai leere das log des containers api ohne ihn zu stoppen→ truncate -s 0 "$(docker inspect --format '{{.LogPath}}' api)"
Der Container schreibt weiter in denselben Dateideskriptor, der Strom reißt nicht ab und der Platz ist sofort wieder da. Genau dieser Befehl hilft während eines Vorfalls.
4. Die Falle: rm statt truncate
$ clai lösche die logdatei des containers api→ rm "$(docker inspect --format '{{.LogPath}}' api)"⚠ CAUTION — danach bleibt docker logs kaputt, bis der Container neu startet
docker logs antwortet dann Error grabbing logs: open …-json.log: no such file or directory, und die Datei kommt nicht von selbst zurück. Der Daemon hält die gelöschte Datei weiter offen, also wird auch der Platz nicht frei: Ausgabe weg, Problem geblieben.
5. Damit es nicht wieder passiert
$ clai starte einen container mit logrotation bei 10 megabyte und drei dateien→ docker run -d --log-opt max-size=10m --log-opt max-file=3 --name api alpine sleep 600
Dateigröße mal Dateianzahl ergibt die Obergrenze — hier 30 MB. Jedem geschwätzigen Container geben.
6. Prüfen, ob ein laufender Container ein Limit hat
$ clai zeige die logging-einstellungen des containers api→ docker inspect -f '{{json .HostConfig.LogConfig}}' api{"Type":"json-file","Config":{"max-file":"3","max-size":"10m"}}
Ein leeres "Config":{} heißt: kein Limit, die Datei wächst bis die Platte voll ist. Genau so sieht ein Container aus, der ohne diese Optionen gestartet wurde.
Gotchas
- Kürzen befreit nur die aktive Datei. Ein Container mit
max-size=1m --log-opt max-file=2schrieb 20000 Zeilen,docker logszeigte alle. Nach dem Kürzen der aktiven Datei waren noch 10122 Zeilen da — der Rest liegt in der rotierten…-json.log.1. Rotierte Dateien löschen, die aktive kürzen. - daemon.json gilt nicht für vorhandene Container.
log-optsin/etc/docker/daemon.jsonwird beim Erstellen gelesen. Laufende Container behalten ihre alten Einstellungen, bis sie neu erzeugt werden. sort -hhängt von der Locale ab. In einer russischen oder deutschen Locale wird6.1Mnicht als Zahl erkannt, und das dickste Log landet mitten in der Liste.LC_ALL=Cvorsortsetzen.
Related questions
Warum zeigt docker system df die Logs nicht? Es zählt Images, Schreibschichten, Volumes und Build-Cache. Die json-Logdateien liegen daneben im Containerverzeichnis und tauchen in dieser Tabelle nie auf.
Wie begrenze ich die Logs aller Container auf einmal? "log-driver": "json-file" und "log-opts": {"max-size": "10m", "max-file": "3"} in /etc/docker/daemon.json eintragen, Daemon neu starten, Container neu erzeugen.
Kann ich Logs komplett von der Platte fernhalten? Ja, --log-driver none schaltet das Sammeln ab, dann zeigt docker logs aber nichts. Der Mittelweg ist der Treiber local, der von Haus aus rotiert.
See also
CliAI macht aus der Formulierung oben den exakten Befehl und kennzeichnet die rm-Variante als CAUTION, bevor irgendetwas läuft. In einer Zeile installieren.