✦ For everyone, free.

Practical knowledge for real and everyday life

Home

19.3.2.5 Prune Volume Caution

A focused guide to Prune Volume Caution, connecting core concepts with practical Docker and container operations.

Volume pruning is the most irreversible cleanup action available in Docker, and it requires careful consideration before execution. Unlike containers, images, or build cache — which can typically be recreated from source — the data inside a Docker volume may be the only copy of application state that exists. Removing a volume permanently deletes its contents with no possibility of recovery.

Why Volume Pruning Is Different

Containers, images, and build cache can all be recreated: re-run the application, rebuild from a Dockerfile, or re-pull from a registry. The data they contain is reproducible. Volumes, however, are specifically designed as the place to store persistent data that must survive container restarts and replacements. This means volumes often hold:

  • Database files (PostgreSQL data directory, MySQL data directory, MongoDB data directory).
  • Application user uploads and files.
  • SSL certificates and secrets.
  • Application state that the application writes during operation.
  • Logs that were intentionally persisted.

Pruning volumes without verification is one of the most common causes of irreversible data loss in Docker environments.

The Volume Prune Command

docker system prune does not remove volumes by default. Volumes are explicitly excluded unless you pass the --volumes flag:

docker system prune --volumes

The confirmation prompt explicitly warns about volumes:

WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all volumes not used by at least one container
  - all dangling images
  - all dangling build cache

Are you sure you want to continue? [y/N]

To prune only volumes without affecting other resource types:

docker volume prune

The confirmation prompt for this command:

WARNING! This will remove anonymous local volumes not used by at least one container.
Are you sure you want to continue? [y/N]

What Gets Removed

Both docker volume prune and docker system prune --volumes remove volumes that are not currently mounted by any container — running or stopped. The pruning logic does not distinguish between named volumes holding important database data and anonymous volumes that were created by accident and contain nothing useful.

If a volume named postgres_data holds an entire production database and no container is currently running (for example, the database container is stopped for maintenance), that volume has 0 links and qualifies for removal by the prune operation.

Identifying Volumes Before Pruning

Before running any volume prune command, review all volumes:

docker volume ls

To see volumes that would be removed (those with no container references):

docker volume ls --filter dangling=true

To see the size of each volume:

docker system df -v

The Volumes section shows each volume name, its LINKS count, and its SIZE. Any named volume with LINKS of 0 and a large SIZE is a candidate for careful review.

To inspect the contents of a volume before deciding whether to remove it:

docker run --rm -v my_volume:/data alpine ls -la /data

This mounts the volume into a temporary Alpine container, lists the contents, and automatically removes the container. The volume is unaffected.

To see which containers have previously used a volume (including stopped containers):

docker ps -a --filter volume=my_volume

Backing Up Before Pruning

If volumes may contain important data but you want to free space, back them up before pruning:

docker run --rm -v my_volume:/data -v $(pwd):/backup alpine tar czf /backup/my_volume_backup.tar.gz -C /data .

This creates a compressed archive of the volume's contents in the current directory. The archive can be used to restore the volume later:

docker volume create my_volume_restored
docker run --rm -v my_volume_restored:/data -v $(pwd):/backup alpine tar xzf /backup/my_volume_backup.tar.gz -C /data

Limiting the Risk with Filters

Volume pruning can be scoped using label filters to avoid accidentally removing important named volumes:

docker volume prune --filter "label=disposable=true"

By labeling volumes created for temporary or test purposes with disposable=true at creation time, prune operations can be limited to only those volumes:

docker volume create --label disposable=true temp_cache

Anonymous Volumes vs. Named Volumes

Anonymous volumes (those with UUID-style names created automatically when a container starts without a named volume at a VOLUME-declared path) are generally safer to prune because they typically contain either nothing important or data that was never intended to persist. Named volumes represent intentional persistent storage and should always be reviewed individually before removal.

Despite this distinction, Docker's volume prune command treats both types the same — all volumes with 0 links are removed. The responsibility for distinguishing important volumes from disposable ones lies entirely with the operator running the command.

The Irreversibility Principle

Volume deletion is permanent. There is no trash bin, no undo command, and no recycle mechanism. Once docker volume prune or docker volume rm completes, the data is gone. The only path to recovery is a backup created before the deletion.

This irreversibility is why volume pruning requires the explicit --volumes flag on docker system prune rather than being included by default — it is the one cleanup operation where accidental execution can cause permanent, unrecoverable harm.