Volume Management
List, inspect, back up, restore and clean up Docker volumes. The docker volume commands for day-to-day operations and data migrations.
Creating a volume is only the start. Real Docker work quickly becomes operational: you need to list volumes, inspect where data lives, remove abandoned storage, estimate disk usage, and sometimes back up or restore data before a migration. That is what volume management is about.
This lesson focuses on the Docker volume commands you use day to day. If named volumes give you persistence, volume management gives you control.
Listing Volumes with docker volume ls
The first command to know is:
docker volume ls
This lists all volumes Docker knows about on the current host.
Example output:
DRIVER VOLUME NAME
local pgdata
local uploads
local build-cache
Why this command matters
You use docker volume ls to:
- verify whether a volume already exists
- spot leftover volumes from deleted containers
- check naming conventions
- understand how many persistent storage objects are on the host
In busy development machines, the list often grows faster than expected.
Filtering output
Docker also supports filter flags with docker volume ls.
docker volume ls --filter dangling=true
That helps narrow the list to volumes matching a condition, such as unused volumes.
Filters are useful when cleaning up large systems because they reduce the chance of deleting something important by mistake.
Inspecting Volumes with docker volume inspect
To see details about a specific volume:
docker volume inspect pgdata
The output is JSON and includes fields like:
NameDriverMountpointCreatedAtLabelsScope
Example structure:
[
{
"Name": "pgdata",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/pgdata/_data",
"CreatedAt": "2026-07-12T12:00:00Z",
"Labels": {},
"Scope": "local"
}
]
What the important fields mean
Name tells you which volume you are looking at.
Driver tells you how Docker manages it. For most local systems, this is local.
Mountpoint shows where the actual data is stored on the Docker host.
Scope is usually local, meaning the volume belongs to the current Docker host.
If you ever need to answer “Where is my data?” or “Which driver is this using?”, docker volume inspect is the right command.
Removing Volumes with docker volume rm
To delete one or more specific volumes:
docker volume rm pgdata
Or:
docker volume rm old-cache temp-data
This permanently removes the volume and its contents.
Why docker volume rm sometimes fails
Docker does not remove a volume that is still in use by a container.
You may see an error like:
Error response from daemon: remove pgdata: volume is in use
That happens when a running or stopped container still references the volume.
How to think about this safely
Before removing a volume:
- confirm no container still needs it
- verify whether the data is disposable or important
- back it up if there is any doubt
The refusal to delete in-use volumes is a useful safety barrier, not an annoyance.
Cleaning Up with docker volume prune
Over time, unused volumes accumulate. To remove all volumes that are not currently used by any container:
docker volume prune
Docker will ask for confirmation. To skip the prompt:
docker volume prune -f
What prune actually removes
docker volume prune removes unused volumes, not every volume on the system.
That sounds safe, but remember: unused does not mean unimportant. A volume can be detached from containers and still hold valuable data you plan to reuse later.
When prune is helpful
- after lots of experiments and tutorials
- after repeatedly creating and deleting Compose projects
- when disk usage is climbing
- as periodic maintenance on a development host
When prune is dangerous
- when you do not know what the old volumes contain
- when a stopped workflow may be restarted later
- on shared or production hosts without review
Treat docker volume prune as a cleanup tool, not as a casual command.
Backing Up a Volume
Volumes are persistent, but persistence is not backup. If the disk fails or a volume is deleted, the data is gone unless you have copied it elsewhere.
A classic Docker backup pattern uses a temporary container to read the volume and create an archive on the host.
docker run --rm -v myvolume:/data -v $(pwd):/backup alpine tar czf /backup/myvolume-backup.tar.gz -C /data .
Breaking the backup command down
--rmremoves the temporary helper container after it exits-v myvolume:/datamounts the Docker volume you want to back up-v $(pwd):/backupmounts your current host directory into the helper containeralpineprovides a lightweight Linux imagetar czf /backup/myvolume-backup.tar.gz -C /data .creates a compressed archive from the volume contents
After the command finishes, myvolume-backup.tar.gz exists in your current host directory.
Why this pattern is common
Docker volumes are managed by Docker, so you do not always want to manipulate their host storage paths directly. Using a helper container lets Docker handle the mount while you copy the data in a portable way.
Restoring a Volume from Backup
Restoring follows the same helper-container idea in reverse.
First, make sure the target volume exists:
docker volume create myvolume
Then restore the archive into it:
docker run --rm -v myvolume:/data -v $(pwd):/backup alpine tar xzf /backup/myvolume-backup.tar.gz -C /data
What this does
- mounts the target volume at
/data - mounts the current directory so the backup file is visible
- extracts the archive into the mounted volume
Now a container that uses myvolume can read the restored data.
Backup and Restore as a Migration Tool
The same tar-based approach is useful beyond disaster recovery. It also helps with migration tasks such as:
- moving data from one Docker host to another
- duplicating a development dataset for testing
- saving application state before a risky upgrade
- cloning a volume into a new environment
For example, you might:
- back up the volume on host A
- copy the archive to host B
- create a volume on host B
- restore the archive into that volume
This is one of the simplest ways to move Docker-managed volume data between machines.
Seeing Disk Usage with docker system df
Docker volume usage contributes to host disk consumption, but it is not always obvious how much. A helpful overview command is:
docker system df
This shows disk usage for Docker objects such as:
- images
- containers
- local volumes
- build cache
Example conceptual output:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 12 4 3.1GB 1.8GB
Containers 5 2 120MB 40MB
Local Volumes 8 3 2.6GB 1.9GB
Build Cache 15 0 900MB 900MB
Why docker system df matters
If your machine suddenly runs low on disk space, volumes are often part of the story. This command helps you identify whether local volumes are a major storage consumer before you start cleaning up.
A Practical Cleanup Workflow
Here is a safe volume management flow for a development machine:
- List volumes:
docker volume ls
- Inspect suspicious ones:
docker volume inspect pgdata
- Check overall space:
docker system df
- Back up anything important:
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine tar czf /backup/pgdata-backup.tar.gz -C /data .
- Remove one known disposable volume if needed:
docker volume rm old-cache
- Prune unused leftovers if you are confident:
docker volume prune
This workflow is safer than jumping straight to mass deletion.
Common Scenarios
Scenario 1: A volume remove fails
You try:
docker volume rm pgdata
Docker says the volume is in use.
Interpretation: at least one container still references it. Find the container, decide whether it should keep the data, then stop or remove the container if deletion is truly intended.
Scenario 2: Disk usage keeps growing
Run:
docker system df
If local volumes are large, inspect your active and dangling volumes. Old database experiments and Compose projects are common causes.
Scenario 3: You need to preserve data before an upgrade
Back up the volume first. Even if the upgrade is expected to be safe, a quick archive is good insurance.
Scenario 4: You want to reuse a dataset on another host
Back up, transfer the archive, create a volume on the destination, and restore.
Best Practices
Use descriptive volume names
Names like postgres-prod-data are easier to manage than vague names like data1.
Back up before destructive operations
If the data matters, archive it first.
Inspect before deleting
A few seconds of inspection can prevent serious data loss.
Prune intentionally
Pruning is helpful, but only after you understand what is unused.
Monitor disk usage periodically
Docker storage grows quietly. docker system df gives you a quick reality check.
Common Beginner Mistakes
-
Confusing persistence with backup A volume surviving container deletion does not protect against host failure or accidental removal.
-
Running prune without review Unused data may still be valuable.
-
Deleting a volume just because the container is gone The whole point of a volume is to outlive the container.
-
Ignoring disk usage until the host is full Storage problems are easier to prevent than to clean up under pressure.
-
Not testing restore procedures A backup only proves its value when it can be restored successfully.
Final Takeaway
Volume management is what turns Docker storage from a mystery into an operational skill. Learn to list volumes, inspect them, remove them carefully, prune only with intent, and back them up before risky changes. If you can manage Docker volumes confidently, you are much better prepared to run stateful containers in both development and production.
Knowledge Check
Question 1: Listing Volumes
Which command lists all Docker volumes on the current host?
Question 2: Removal Safety
Why might docker volume rm myvolume fail?
Question 3: Backup Pattern
Why is a temporary helper container commonly used to back up a Docker volume?
Frequently Asked Questions
How do I list and inspect Docker volumes?
docker volume ls lists them, and docker volume inspect <name> shows the driver, mountpoint and any labels. To see what is actually inside one without a running container, mount it into a throwaway container: docker run --rm -v myvolume:/data alpine ls -la /data. That trick works for any volume regardless of platform, which matters on macOS and Windows where the real path lives inside the Docker VM and is not browsable from the host.
Why does docker system prune not remove my volumes?
Because volumes are excluded by default, deliberately. They usually hold the data you least want to lose. docker system prune removes stopped containers, unused networks, dangling images and build cache, but leaves volumes alone unless you add --volumes. Use docker volume prune to remove volumes no container references, and check docker volume ls first, since a volume that looks unused may simply belong to a container you stopped.
How do I find which container is using a volume?
docker ps -a --filter volume=<name> lists containers referencing it, including stopped ones. docker volume inspect does not show consumers, which is a common source of confusion. This matters before pruning, since a volume attached only to a stopped container still counts as in use and will not be removed, while one whose container was deleted becomes eligible immediately.
How do I move a Docker volume to another host?
Archive it through a temporary container and transfer the archive: docker run --rm -v myvolume:/data -v $(pwd):/backup alpine tar czf /backup/vol.tar.gz -C /data ., then reverse the process on the destination after creating an empty volume there. There is no built-in volume migration command. For databases, use the engine's own dump and restore rather than a filesystem copy, which can capture an inconsistent state if the database is running.
How do I reclaim disk space used by Docker volumes?
Start with docker system df -v, which breaks down usage per volume and shows which are unused. Then docker volume prune removes those with no container attached. Be deliberate. Unlike image pruning, this deletes data permanently and there is no recovery. Anonymous volumes created implicitly by images with a VOLUME instruction are a common hidden consumer, since each docker run creates a fresh one that nothing subsequently references.
What are anonymous volumes and why do I have so many?
When an image declares VOLUME /data and you run it without mounting anything there, Docker creates an anonymous volume with a random hexadecimal name. Every docker run creates another, so repeatedly starting such an image, database images commonly do this, leaves a trail of orphaned volumes holding real data. Mount a named volume explicitly to avoid it, add --rm which removes anonymous volumes on exit, and run docker volume prune periodically to clear the ones already accumulated.