Reclaimed 22GB of vDisk space, reducing usage from 89% to 31%
My Unraid Docker vDisk crept up to 89% capacity. Stopped containers, dangling images, and orphaned volumes had accumulated from months of tinkering. This post covers how I recovered 22GB and got back down to 31% without touching anything I actually needed.
The Problem#
The Docker vDisk on Unraid has a fixed size. When it fills up, containers can start behaving unpredictably and new pulls fail. At 89% I was close enough to the limit that it needed to be dealt with before something broke.
The tricky part is that docker system df shows a reclaimable number that is often misleading. It only counts truly dangling images, not images that are still referenced by stopped containers. The real opportunity was hidden behind months of test containers that had been stopped and forgotten.
The Goal#
Recover enough space to get the vDisk back to a comfortable level without removing anything actively in use. No nuclear options, no wiping everything and starting fresh.
The Build#
The Investigation#
SSH into Unraid and get a clear picture of what is consuming space:
docker system dfMy output:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 32 30 32.24GB 3.442GB (10%)
Containers 31 12 904MB 103.4MB (11%)
Local Volumes 16 2 1.045GB 1.045GB (100%)
Build Cache 0 0 0B 0B32 images at 32GB with only 3.4GB showing as reclaimable. 31 containers but only 12 active. 16 volumes with 14 of them completely unused. The low reclaimable number on images was the key clue. Stopped containers were still referencing images, preventing them from being counted as reclaimable.
To see which images were taking the most space:
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | sort -k3 -hThe top offenders:
ghcr.io/blakeblackshear/frigate stable-tensorrt 6.63GB
lscr.io/linuxserver/orcaslicer latest 4.33GB
gitlab/gitlab-ce latest 3.96GB
lscr.io/linuxserver/webtop ubuntu-xfce 2.91GB
agregarr/agregarr latest 1.98GB
ghcr.io/harborguard/harborguard latest 2.05GBFrigate, OrcaSlicer, Webtop, agregarr, and harborguard were all test containers spun up and forgotten. GitLab is legitimately in use so that stayed. Those five alone represented around 17GB.
The Investigation: Why the Reclaimable Number Was Wrong#
The order of operations matters here. Images cannot be removed while a container, even a stopped one, still references them. The stopped containers needed to go first before the images would show as reclaimable.
Listing all containers including stopped ones confirmed several that had been dead for 8 weeks:
docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"The Fix#
Step 1: Remove stopped containers
docker rm adguardhome-sync cronmaster cadvisor doku diun dozzle \
mkvtoolnix makemkv handbrake orcaslicer frigate webtopAfter this, the reclaimable image count jumped from 3.4GB to 10.93GB.
Step 2: Remove unused images
docker rmi ghcr.io/blakeblackshear/frigate:stable-tensorrt
docker rmi lscr.io/linuxserver/webtop:ubuntu-xfce
docker rmi agregarr/agregarr:latest
docker rmi ghcr.io/harborguard/harborguard:latestIf a removal fails because a stopped container is still referencing the image, check the error for the container ID and force remove it first:
docker rm -f <container-id>
docker rmi <image>Then clean up remaining dangling images:
docker image prune -fStep 3: Remove orphaned volumes
All 14 unused volumes had hash-based names, meaning they were created automatically by containers that no longer exist. Most cleared with:
docker volume prune -fA handful of named volumes from a Fleet install were also orphaned:
docker volume rm fleet_data fleet_logs fleet_mysql fleet_redis fleet_vulndbResults#
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 12 12 9.853GB 78.13MB (0%)
Containers 12 12 800.8MB 0B (0%)
Local Volumes 1 1 0B 0B
Build Cache 0 0 0B 0BImages went from 32.24GB down to 9.85GB. Containers went from 31 total down to 12, all active. Volumes went from 16 down to 1. Docker vDisk dropped from 89% to 31%. The whole cleanup took about 20 minutes and most of that was identifying what was safe to remove.
What I Would Do Differently#
I would not let it get to 89% in the first place. A periodic docker system df check, even just monthly, would catch drift long before it becomes urgent. The bigger lesson is that test containers should be removed immediately after testing rather than left stopped indefinitely. A stopped container feels harmless but it is silently holding onto its image and preventing cleanup.
What Is Next#
Going forward I added log rotation to all Docker Compose services to prevent container logs from silently growing:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"I also added docker system df to my monthly maintenance checklist so this does not creep up again unnoticed.
Quick Reference#
# See space usage breakdown
docker system df
# List all containers including stopped
docker ps -a
# List images sorted by size
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | sort -k3 -h
# Remove specific stopped containers
docker rm container1 container2
# Remove dangling images only
docker image prune -f
# Remove all unused images
docker image prune -a -f
# Remove orphaned volumes
docker volume prune -f
# Remove everything unused in one shot
docker system prune -a -f --volumesThe last command removes everything not attached to a running container. Use it only if you are confident nothing stopped is worth keeping.