Docker: Why docker bind mounts instead of docker volumes

Introduction

Note, with the text below, you could potentially break your docker installation. Use with care. This post has been updated 2025-10-13 with more warnings.

This post is about cleaning up:

  • Dangling images, after you have done multiple docker build, docker pull, and you end up having multiple versions of the same container.
  • Hanging overlay2 after dead containers (i.e you rebooted a server abruptly)

There are many reasons why a container would waste space in your system.

  • You were using docker volumes instead of bind mounts

The first thing you should try is always these, which will also be dangerous if you don’t know what you are doing. For example, I never use docker volumes (stored in /var/lib/docekr/volumes), but rather bind mounts. So for me, removing dangling volumes is harmless.

Docker commands to clean up:

#--- removing old images is quite harmless
docker image list
docker image prune
docker image prune -a

#--- remove volumes if you know that you are only using bind mounts
docker volume list
docker volume prune
docker volume prune -a

#--- remove old, dangling overlays, caches, non running containers (including overlays), networks
docker system prune
docker system prune -a

Manually cleaning up

This should always come as a last resort. Be careful. You have been warned.

Situation: Your monitoring is warning that the root filesystem of a docker host is filling up. You realize that one or more containers are filling up their corresponding overlay2 filesystems.

root@prd-docker-l01:/var/lib/docker/overlay2# du -hs * | sort -h
912M	e050850d947bab0a1bf1143d0514a65070a651fc2a01dee87711704542bb7ec1
1.1G	2e910edbec7e137655736f38185680ef8a5948c22e74c02e1bd121c9adabc265
1.3G	2e9f4aa26682df9a0e3e19ac07cdbc7eca29f506d695e8adc337409cab90809e
1.5G	80f8c9d45565aa68a75e1f8dd7f5aa0c98dc1bf3ae7a041ffcaa799889a0325d

root@prd-docker-l01:/var/lib/docker/overlay2# du -hs .
21G	.

Which container’s overlay2 is growing?

docker ps -q | while read -r container_id; do overlay_dir=$(docker inspect --format='{{.GraphDriver.Data.MergedDir}}' $container_id | sed 's:/merged$::'); overlay_id=$(basename $overlay_dir); size=$(du -hs $overlay_dir | awk '{print $1}'); container_name=$(docker ps | grep $container_id | awk '{print $NF}') ; echo "$size Container: $container_name/$container_id - Overlay: $overlay_id - Size: $size"; done | sort -h

912M Container: my-container-1/cd9885b986fb - Overlay: e050850d947bab0a1bf1143d0514a65070a651fc2a01dee87711704542bb7ec1 - Size: 912M
1.1G Container: admin-gui-admin-gui-1/719714a4275a - Overlay: 2e910edbec7e137655736f38185680ef8a5948c22e74c02e1bd121c9adabc265 - Size: 1.1G
1.5G Container: some-other-container-1/4c6ec45fe606 - Overlay: 80f8c9d45565aa68a75e1f8dd7f5aa0c98dc1bf3ae7a041ffcaa799889a0325d - Size: 1.5G

Bonus: Find overlay2 directories that can be deleted (not belonging to running containers). Do not delete the l directory.

find /var/lib/docker/overlay2 -mindepth 1 -maxdepth 1 -type d \! -exec bash -c "docker ps -q | xargs docker inspect --format '{{.GraphDriver.Data}}'| grep -q "{} \; -print

References