How to Fix Disk Space Issues on a Docker VPS Without Breaking Your Apps
Recover space on a crowded Docker server with a safer sequence that helps you avoid deleting the exact data your apps still need.
How to find where space is going, clean up old Docker artifacts, rotate logs, and protect named volumes and live app data.
Small VPS setups running Docker Compose apps, reverse proxies, databases, and utility containers.
docker system prune --volumes can delete data you expected to keep. Do not run it casually on a live server.
Before you begin
- SSH access to the VPS and enough privileges to inspect Docker, logs, and system paths.
- A recent backup of important databases and volume data if the server is truly near failure.
- An understanding of which containers are production-critical and which are disposable.
When a Docker VPS fills up, the danger is not just that it stops working. The danger is panic-cleaning. Many operators free space fast, then discover they removed the image cache needed for a restart or deleted a volume that held real data. The goal is to create breathing room without making recovery harder.
Step 1: Find what is actually using the disk
Start with the whole filesystem, then zoom in. You want evidence before deletion.
df -h
sudo du -xh / --max-depth=1 | sort -h
sudo du -xh /var --max-depth=1 | sort -h
sudo du -xh /var/lib/docker --max-depth=2 | sort -h | tail -n 20
docker system dfThese commands tell you whether the main problem is Docker images, stopped containers, build cache, JSON logs, package caches, or something outside Docker entirely.
Pay special attention to these paths:
/var/lib/docker/overlay2for image layers and writable container layers/var/lib/docker/volumesfor named volumes/var/lib/docker/containersfor JSON logs/var/logfor system logs
Step 2: Clean Docker in the safest order
Start with unused items that are least likely to hurt a running app.
Remove stopped containers:
docker container pruneRemove dangling images:
docker image pruneRemove old build cache:
docker builder pruneReview overall reclaimable space:
docker system df -vIf you need a bigger cleanup, this is often still safe enough on many servers:
docker system pruneThat removes stopped containers, unused networks, dangling images, and build cache. It does not remove named volumes unless you add --volumes.
Be very careful with volume cleanup. First, list volumes and see which ones are attached:
docker volume ls
docker ps --format 'table {{.Names}}\t{{.Mounts}}'If a volume looks unused, inspect it before removal:
docker volume inspect my_volumeOnly remove an unused volume when you are certain it is not needed:
docker volume rm my_old_unused_volumeFor Compose stacks, compare running services with declared volumes so you do not delete data from an app you just forgot about.
Step 3: Check logs, apt caches, and big one-off files
Docker log files can grow massively, especially for noisy apps.
sudo find /var/lib/docker/containers -name '*-json.log' -exec du -h {} + | sort -h | tail -n 20If a log file is huge, truncate it rather than deleting the container directory:
sudo truncate -s 0 /var/lib/docker/containers/CONTAINER_ID/CONTAINER_ID-json.logThen add log limits in Compose so the problem does not come back:
services:
app:
logging:
options:
max-size: "10m"
max-file: "3"Check system logs and package caches too:
sudo journalctl --disk-usage
sudo journalctl --vacuum-time=7d
sudo apt clean
sudo du -xh /var/log --max-depth=1 | sort -hAlso look for forgotten backups, dumps, and tarballs in places like /tmp, /root, and home directories:
sudo find /tmp /root /home -type f -size +200M -printf '%p %k KB\n' | sort -nStep 4: Prevent the same disk emergency next week
Once the server has breathing room, make the cleanup habits permanent.
- Add Docker log rotation options to noisy services.
- Schedule periodic review of
docker system df. - Move backup files off the main VPS after they are created.
- Set retention for app logs and system logs.
- Monitor disk usage with a tool like Netdata or Uptime Kuma.
If your disk usage is driven by databases or uploads rather than junk, cleanup is not the real fix. You may need a larger disk, offsite object storage, or a stronger backup retention policy.
Rollback and recovery notes
If you remove the wrong image, you can usually pull or rebuild it again. If you remove the wrong volume, recovery is much harder and depends on backups.
- If a container fails after cleanup, run
docker compose up -dor repull the missing image. - If logs were truncated, the app should continue running, but historical log context is gone.
- If you deleted a needed volume, stop writing to the app and restore from backup before making the state worse.
This is why safe cleanup starts with stopped containers, dangling images, and logs, not live storage.
Step 5: Verify the server is healthy again
After cleanup, confirm both free space and app health:
df -h
docker system df
cd /opt/myapp && docker compose ps
curl -I https://example.comYou should see:
- More free space on the root filesystem
- All production containers still running
- No missing uploads or broken database connections
- Reduced risk of immediate disk exhaustion
Troubleshooting common disk cleanup issues
Disk is still full after Docker cleanup.
The real usage may be in logs, backups, package caches, or another mount point outside Docker.
Cleanup freed space, but the app still crashes.
A full disk may already have corrupted temp files, failed writes, or stopped services. Check app logs and restart the affected containers.
overlay2 is huge even after pruning.
Some running containers may have large writable layers. Inspect noisy apps, temporary file paths, and container log behavior.
I need more space, but everything left looks important.
That usually means you have a capacity problem, not a cleanup problem. Expand the disk or move durable assets elsewhere.
What to do next
Once disk usage is under control, the next helpful improvement is real monitoring so you catch the trend before the VPS is full again. Continue with Monitor Disk, CPU, and Memory on a VPS With Netdata.
