A full disk is one of those Linux problems that looks simple until you actually have to find the cause.
You run:
df -h
and discover:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 24G 23G 0 100% /
At this point, the temptation is to start deleting things from /var, /tmp, or /home.
Don't.
The better approach is to find where the space actually went, then decide what is safe to remove.
Start with df
First, find out which filesystem is full:
df -h
df tells you how much space is used on each mounted filesystem. It doesn't tell you what is using that space.
For example:
/dev/vda1 24G 23G 0 100% /
This tells us that the root filesystem is full, but not whether the problem is /home, /var, Docker, logs, or something else.
Find the largest directories
For the root filesystem, use:
sudo du -xhd1 / 2>/dev/null | sort -h
The -x is important. It keeps du on the same filesystem, so mounted filesystems don't distort the result.
You might get something like:
3.1G /home
3.3G /usr
14G /var
22G /
Now we know where to look.
If /var is the problem:
sudo du -xhd1 /var 2>/dev/null | sort -h
Continue drilling down until you find the actual source.
For example:
268M /var/cache
364M /var/www
3.6G /var/log
9.0G /var/lib
14G /var
At this point, /var/lib and /var/log deserve attention.
Logs can quietly consume gigabytes
System logs are one of the easiest ways for a server to slowly run out of space.
Check:
sudo du -xhd1 /var/log 2>/dev/null | sort -h
On a system using systemd, also check:
sudo journalctl --disk-usage
You may discover that the journal is consuming gigabytes:
Archived and active journals take up 2.4G in the file system.
If you don't need that much historical journal data, you can reduce it:
sudo journalctl --vacuum-size=200M
Or retain only a specific amount of history:
sudo journalctl --vacuum-time=7d
For a small server, setting a sensible journal limit is usually better than repeatedly cleaning it manually.
For example, create:
sudo mkdir -p /etc/systemd/journald.conf.d
sudo nano /etc/systemd/journald.conf.d/size.conf
and configure:
[Journal]
SystemMaxUse=200M
SystemKeepFree=1G
Then restart the journaling service:
sudo systemctl restart systemd-journald
Docker is another common culprit
If you run Docker, /var/lib/docker can become one of the largest directories on the server.
Check:
sudo du -xhd1 /var/lib/docker 2>/dev/null | sort -h
You may see:
857M /var/lib/docker/volumes
3.0G /var/lib/docker/containers
4.1G /var/lib/docker/overlay2
8.0G /var/lib/docker
Docker provides another useful command:
sudo docker system df
It separates Docker's storage into images, containers, volumes, and build cache.
For example:
TYPE TOTAL ACTIVE SIZE
Images 21 10 4.078GB
Containers 10 9 112.9MB
Local Volumes 46 9 1.588GB
Build Cache 0 0 0B
This is much more useful than simply looking at /var/lib/docker.
Don't blindly delete Docker data
Avoid doing this:
sudo rm -rf /var/lib/docker/*
That can destroy your containers, images, volumes, and application data.
Likewise, don't automatically run:
docker system prune -a
on a production server.
An old image may be useful for rollback, and an apparently unused volume may contain important application data.
Inspect first.
For unused images:
sudo docker image prune
For unused volumes:
sudo docker volume prune
Be particularly careful with volumes because they can contain databases and persistent application data.
Docker logs deserve special attention
There is another Docker problem that is easy to miss.
With the default json-file logging driver, container stdout/stderr can accumulate in:
/var/lib/docker/containers/
Check the size:
sudo du -xhd1 /var/lib/docker/containers 2>/dev/null | sort -h
And find the actual log files:
sudo find /var/lib/docker/containers \
-name '*-json.log' \
-exec du -h {} + | sort -h
You might find something like:
98M .../919126...-json.log
2.9G .../44bfd8...-json.log
Now you have found the real problem.
A single container can generate gigabytes of logs while the application itself is using very little disk space.
You can identify the container:
sudo docker ps -a --no-trunc
If you need to immediately reclaim space from a huge Docker JSON log, the log can be truncated without removing the container:
sudo truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log
However, this is only a temporary fix.
The real solution is log rotation.
Configure Docker log rotation
For servers using Docker's json-file driver, configure limits in:
/etc/docker/daemon.json
For example:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
This limits each container's log files instead of allowing them to grow indefinitely.
Be aware that changing Docker's daemon configuration does not retroactively change the logging configuration of already-created containers. Existing containers may need to be recreated for the new logging settings to apply.
So don't restart Docker blindly on a production server just because you want to change logging. Plan the container recreation appropriately.
Check for deleted files still consuming space
Sometimes du and df appear to disagree.
For example:
df -h
might say:
/dev/vda1 24G 23G 0 100% /
while:
sudo du -sh /
appears to account for considerably less.
One possible reason is a process holding an already-deleted file open.
Find those files with:
sudo lsof +L1
A process can continue consuming disk space through an open file even after the filename has been deleted.
Restarting the relevant process releases that space.
This is particularly common with large log files.
Look for unusually large individual files
Once you've narrowed down the filesystem, you can search for large files:
sudo find / -xdev -type f -printf '%s %p\n' 2>/dev/null \
| sort -nr \
| head -30
For human-readable sizes:
sudo find / -xdev -type f -printf '%s %p\n' 2>/dev/null \
| sort -nr \
| head -30 \
| numfmt --field=1 --to=iec
This is useful for discovering things such as:
-
giant application logs
-
database dumps
-
forgotten backups
-
core dumps
-
large archives
-
Docker logs
What about /var/cache?
Package caches usually aren't the biggest problem, but they can be cleaned safely.
On Debian/Ubuntu:
sudo apt clean
You can inspect the cache first:
sudo du -sh /var/cache/apt
Don't expect miracles if it's only a few hundred megabytes.
Don't automatically delete /tmp
A common reaction to a full disk is:
sudo rm -rf /tmp/*
I wouldn't make this your first move.
/tmp is often not the source of the problem, and applications may currently be using files there.
Investigate first:
sudo du -xhd1 /tmp 2>/dev/null | sort -h
Only clean it when you know it is actually contributing significantly to the problem.
A practical investigation sequence
When a Linux server suddenly runs out of disk space, I use this order:
df -h
Then:
sudo du -xhd1 / 2>/dev/null | sort -h
Then drill into the largest directory:
sudo du -xhd1 /var 2>/dev/null | sort -h
For logs:
sudo du -xhd1 /var/log 2>/dev/null | sort -h
sudo journalctl --disk-usage
For Docker:
sudo du -xhd1 /var/lib/docker 2>/dev/null | sort -h
sudo docker system df
For Docker logs:
sudo find /var/lib/docker/containers \
-name '*-json.log' \
-exec du -h {} + | sort -h
And if df and du don't agree:
sudo lsof +L1
This gives you a systematic path from:
"My disk is full" → "This directory is large" → "This particular service is responsible."
The important lesson
A full Linux filesystem is not usually solved by deleting random files.
The useful distinction is between space that is genuinely required and space that accumulated unintentionally.
In a real server investigation, you might discover that /var is using 14 GB. Drilling down might reveal 3.6 GB of logs and 9 GB of Docker data. Further investigation could reveal that the Docker data contains a single 2.9 GB container log.
At that point, the solution isn't "clean Docker."
It's:
-
identify the container producing the logs,
-
reclaim the accumulated log space,
-
determine why it is producing so much output,
-
configure log rotation so the problem doesn't return.
That's the difference between cleaning up disk space and fixing the disk-space problem.
A few minutes of df, du, and targeted investigation can usually tell you exactly where the disk went—without risking your applications or their data.