truncate -s 0 "$(docker inspect --format '{{.LogPath}}' api)" empties the log of a running container and frees the space immediately, with no restart. Never use rm here: the daemon keeps writing into the deleted file, so the space is not returned and docker logs stays broken until the container restarts.
1. First see what Docker is actually holding
$ clai how much disk space does docker use→ 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 are invisible in this table — the Containers row counts writable layers only. When df says the disk is full and docker system df looks calm, logs are the suspect.
2. Find the container that writes the most
$ clai show the log file size of every container, largest first→ 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 is the only reliable way to locate the file — it differs between rootful and rootless installs. LC_ALL=C is not decoration: in a locale where the decimal separator is a comma, sort -h puts 844K above 6.1M.
3. Truncate the log of a running container
$ clai empty the log of the api container without stopping it→ truncate -s 0 "$(docker inspect --format '{{.LogPath}}' api)"
The container keeps writing into the same file descriptor, so the stream survives and the space comes back at once. This is the one command you want during an incident.
4. The trap: rm instead of truncate
$ clai delete the log file of the api container→ rm "$(docker inspect --format '{{.LogPath}}' api)"⚠ CAUTION — after this docker logs stays broken until the container restarts
docker logs then answers Error grabbing logs: open …-json.log: no such file or directory, and the file does not come back by itself. The daemon still holds the deleted file open, so the disk space is not returned either — you lose the output and keep the problem.
5. Make sure it cannot happen again
$ clai run a container with log rotation at 10 megabytes and three files→ docker run -d --log-opt max-size=10m --log-opt max-file=3 --name api alpine sleep 600
One file size times the number of files is the ceiling — 30 MB here. Set it on every container that talks a lot.
6. Check whether a running container has a cap
$ clai show the logging settings of the api container→ docker inspect -f '{{json .HostConfig.LogConfig}}' api{"Type":"json-file","Config":{"max-file":"3","max-size":"10m"}}
An empty "Config":{} means there is no limit at all and the file will grow until the disk ends. That is exactly how a container started without those options looks.
Gotchas
- Truncating frees only the active file. A container capped at
max-size=1m --log-opt max-file=2wrote 20000 lines anddocker logsshowed all of them. After truncating the active file 10122 lines were still there — the rest live in the rotated…-json.log.1. Delete the rotated files, truncate the active one. - daemon.json does not apply to existing containers.
log-optsin/etc/docker/daemon.jsonis read when a container is created. Running containers keep their old settings until you recreate them. sort -hdepends on your locale. In a Russian or German locale6.1Mis not parsed as a number and the biggest log lands somewhere in the middle of the list. PutLC_ALL=Cin front ofsort.
Related questions
Why doesn't docker system df show the logs? It counts images, container writable layers, volumes and build cache. The json log files sit next to them in the container directory and never enter that table.
How do I cap logs for every container at once? Put "log-driver": "json-file" and "log-opts": {"max-size": "10m", "max-file": "3"} into /etc/docker/daemon.json, restart the daemon, then recreate the containers.
Can I skip writing logs to disk entirely? Yes, --log-driver none turns collection off, but then docker logs shows nothing. The middle ground is the local driver, which rotates by default.
See also
CliAI turns the phrasing above into the exact command and labels the rm variant CAUTION before anything runs. Install it in one line.