VPS Tutorials
VPS Docker Disk Full: What to Do (2026): overlay2, Container Logs, Images, and Volume Cleanup Checklist
Docker on a VPS can easily fill up the system disk: overlay2 layers, stopped containers, old images, build cache, json-file logs, and orphaned volumes can all take up space. This article walks through troubleshooting in order: df, docker system df, log rotation, safe prune, and volume protection, so a single command doesn't accidentally delete your data.

VPS Docker Disk Full: What to Do (2026): overlay2, Container Logs, Images, and Volume Cleanup Checklist
Docker is convenient to deploy with, but on a small-disk VPS it can easily fill up the system disk. The most common scenario: the website is still running, but df -h shows / already at 100%; or apt install, database writes, and log persistence all fail, and you finally discover that overlay2 under /var/lib/docker, container logs, old images, and build cache are taking up tens of GB.
Don't just run rm -rf /var/lib/docker/overlay2 right away for this kind of problem. overlay2 is Docker's storage layer, and it may contain the writable layers of running containers; deleting it directly can easily corrupt container state. The right approach is to first confirm where the space went, then clean up from lowest risk to highest.
First check system disk usage:
df -h
If / or /var is full, then check the Docker directory size:
sudo du -h --max-depth=1 /var/lib/docker | sort -h
Common big consumers usually include these:
/var/lib/docker/overlay2
/var/lib/docker/containers
/var/lib/docker/volumes
/var/lib/docker/buildkit
Then look at space distribution from Docker's own perspective:
docker system df
docker system df -v
docker system df shows images, containers, local volumes, and build cache separately, which is safer than only looking at du. du tells you which directory is large; Docker commands tell you what objects that space belongs to.
Docker's official documentation also states clearly: Docker takes a conservative approach to unused objects; images, containers, networks, and volumes are not automatically cleaned up by default unless you explicitly run prune.
First look at stopped containers:
docker ps -a
If there are many exited temporary containers, you can clean up stopped containers:
docker container prune
Then look at images:
docker images
Clean up only dangling images:
docker image prune
Clean up old images not used by any container:
docker image prune -a
If you're not sure whether an image is still needed for rollback, don't add -a yet. In production, image prune -a may delete images that aren't currently referenced by a container but that you intended to keep for rollback.
On machines that frequently run docker build on the VPS, the build cache may be larger than the images themselves. Check:
docker builder du
Clean up build cache:
docker builder prune
If you're sure you don't need any old cache, then consider:
docker builder prune -a
A safer approach is to add a time filter, for example only cleaning cache older than 7 days:
docker builder prune --filter "until=168h"
This is more suitable for a live VPS than blindly deleting everything, because it reduces the impact of re-pulling and recompiling on the next build.
Many people only watch overlay2, but what actually fills the disk is container logs. Docker's default json-file logging driver writes stdout and stderr to files. If the application keeps printing error logs and there's no log rotation, a single container log can grow to several GB.
Check container log file sizes:
sudo du -h /var/lib/docker/containers/*/*-json.log | sort -h
To stop the bleeding temporarily, first locate the abnormal container:
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Image}}"
docker logs --tail=100 容器名
Don't open huge json logs directly in an editor. More importantly, fix the source of the logs: is the application looping on errors, are health checks too frequent, is the reverse proxy constantly retrying.
The long-term solution is to configure log rotation for Docker. Edit:
sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json
Write or merge the following configuration:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Then restart Docker:
sudo systemctl restart docker
Note: this configuration usually only affects newly created containers. Existing containers may need to be recreated to use the new logging options. If you use Docker Compose, it's recommended to run:
docker compose down
docker compose up -d
Provided you've confirmed the compose file and volume configuration are correct.
/var/lib/docker/volumes may be large, but it often stores databases, uploaded files, configuration, and queue data. This directory cannot be lumped together with image cache.
First check volume usage:
docker system df -v
List volumes:
docker volume ls
If you want to determine whether a volume is still used by a container:
docker ps -a --filter volume=卷名
Docker provides:
docker volume prune
But this command deletes volumes not used by containers. The problem is: during some maintenance downtime, the database container may temporarily not exist, but the volume is still your only data. In production, don't run volume prune without a backup and without confirming the purpose.
A safer order is:
- Back up important volumes first;
- Confirm the compose project is abandoned;
- Confirm the volume name is not a database, object storage, or upload directory;
- Then delete the specified volume by name.
docker volume rm 卷名
docker system prune is a quick cleanup command that cleans stopped containers, unused networks, dangling images, and build cache. By default it does not clean volumes.
The relatively safe version:
docker system prune
With a time filter:
docker system prune --filter "until=168h"
The high-risk version:
docker system prune -a --volumes
This command is not suitable as a "universal cleanup" in a beginner tutorial. -a expands the scope of image cleanup, and --volumes includes unused volumes in cleanup. For a VPS running WordPress, Nextcloud, Gitea, or a database, once the volume judgment is wrong, what gets cleaned up may be business data.
Not recommended. overlay2 is the storage directory for Docker's overlay filesystem, not an ordinary cache directory. It growing larger is usually just a result; the cause may be:
- The container writable layer keeps writing temporary files;
- The application writes cache and uploaded files inside the container instead of to a volume;
- Old images and old containers haven't been cleaned up;
- Build cache accumulates over time;
- Logs have no rotation.
First find containers with abnormal writable layers:
docker ps -s
If a container's SIZE is very large, its writable layer is expanding. Common causes are the application writing cache, uploaded files, and export files inside the container. The fix is not to delete overlay2, but to mount persistent directories to a volume or host directory and adjust the application configuration.
It's recommended to handle it in this order:
df -hto confirm which partition is full;sudo du -h --max-depth=1 /var/lib/docker | sort -hto find large Docker directories;docker system df -vto determine the proportions of images, containers, volumes, and build cache;- First clean stopped containers and dangling images;
- Then clean build cache;
- Check json-file logs and configure rotation;
- Only then handle volumes;
- Don't delete
overlay2directly.
If your VPS only has a 20GB or 30GB system disk, you should do three things before deploying Docker:
- Set
max-sizeandmax-filefor Docker logs; - Put databases, upload directories, and business data into clearly named volumes or a separate data disk;
- Regularly run commands that only clean old cache, for example:
docker system prune --filter "until=168h"
docker builder prune --filter "until=168h"
Also keep monitoring:
df -h
docker system df
If you've already hit a full disk, don't restart a bunch of services first. When the disk is 100% full, databases, logging services, and package managers may all fail to write. First free up a small amount of safe space, then fix the root causes one by one.
Docker filling up the disk on a VPS looks like overlay2 being too large, but it's often actually old images, stopped containers, build cache, json-file logs, and volume management mixed together. The truly safe way to handle it is not to delete the Docker directory, but to first classify with docker system df -v, then clean up from lowest risk to highest.
Remember this bottom line: images and cache can be re-pulled, stopped containers can usually be cleaned, logs can be rotated, but volumes may contain your business data. Confirm before cleaning, and after cleaning add log rotation and regular maintenance rules, so you won't be interrupted by the same problem again in a few weeks.