Audit Docker Volumes Safely with docker volume ls
You will finish with a repeatable, read-only way to inventory Docker volumes, find a particular volume, filter by ownership clues, and produce output suitable for a script or report. Allow about ten minutes. You need the Docker CLI and access to the Docker daemon; no elevated privilege is normally needed.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide uses Docker CLI 29.8.1 from the installed docker-ce-cli package, version 5:29.8.1-1~ubuntu.24.04~noble. Output varies with the volumes present on your host.
1. Confirm the command and daemon access
Start with the built-in help. This is an ordinary read-only command:
$ docker volume ls --help
Usage: docker volume ls [OPTIONS]
List volumes
Check the client version separately, then ask Docker for the current inventory:
$ docker version --format '{{.Client.Version}}'
29.8.1
$ docker volume ls
DRIVER VOLUME NAME
local example-data
The normal table has a driver column and a volume name column. If the last command reports a daemon connection error, stop there. Check that Docker is running and that your account can access its socket. Use sudo only if your host's Docker setup explicitly requires it; adding privilege does not fix a stopped or remote daemon.
Checkpoint
You have a version number and a successful unfiltered listing, or a specific daemon-access error to resolve.
2. Read the full inventory without touching data
docker volume ls lists volumes known to Docker, not files found by scanning the host filesystem. It does not mount, inspect, create or remove a volume. An empty table is a valid result if this Docker environment has no volumes.
For a compact list that is easy to pass to another command, use --quiet:
$ docker volume ls --quiet
example-data
cache-data
Names are the safest field to feed into a later Docker command. Keep one name per line and do not assume that a volume name is a directory path. Docker volume data is managed by the volume driver.
3. Find volumes by name or driver
Filters use a key=value form. The name filter matches all or part of a volume name, so use a distinctive fragment:
$ docker volume ls --filter 'name=project'
DRIVER VOLUME NAME
local project-db
local project-uploads
To see only volumes using a particular driver, use driver. The common built-in driver is local, but a volume created by a plugin may use another driver name:
$ docker volume ls --filter 'driver=local'
DRIVER VOLUME NAME
local example-data
The output is host-specific. A blank result means the filter matched nothing; it is not an error. You can pass more than one filter flag when narrowing a report:
$ docker volume ls --filter 'driver=local' --filter 'name=project'
Do not confuse a partial name match with an exact lookup. Before using a returned name in a later operation, copy it from --quiet output or verify it with docker volume inspect.
4. Use labels as an ownership check
Labels are useful when several projects share one Docker host. A label-only filter matches volumes carrying that key, regardless of its value:
$ docker volume ls --filter 'label=project'
DRIVER VOLUME NAME
local project-db
Include a value when you need a narrower result:
$ docker volume ls --filter 'label=project=payments'
DRIVER VOLUME NAME
local payments-db
Quote the complete filter. This protects label values containing shell-significant characters and makes the key-value boundary visible. A missing or misspelled label produces no matching rows; it does not search the volume's contents.
5. Identify volumes that are not referenced by containers
The dangling filter selects volumes that are not referenced by any containers. This is useful for review, not automatic housekeeping:
$ docker volume ls --filter 'dangling=true'
DRIVER VOLUME NAME
local old-cache
Use false to list volumes that are referenced, or 1 and 0 as the boolean forms accepted by this command:
$ docker volume ls --filter 'dangling=false' --quiet
project-db
project-uploads
Safety boundary
Finding a dangling volume does not prove that its data is disposable. A stopped workflow, an external consumer, a recovery plan or a naming mistake may make it valuable. Do not follow this listing with docker volume prune or docker volume rm until you have checked ownership, backups and retention requirements. Those commands change or remove state, and this listing command has no undo operation for them.
6. Produce stable output for a report
Use --format when column spacing is not suitable for automation. A Go template can select fields without headers:
$ docker volume ls --format '{{.Name}}: {{.Driver}}'
example-data: local
project-db: local
Useful placeholders include .Name, .Driver, .Scope, .Mountpoint, .Labels and .Label. For example, this records names and scopes:
$ docker volume ls --format '{{.Name}} {{.Scope}}' > volume-report.tsv
$ sed -n '1,5p' volume-report.tsv
example-data local
The redirection creates or replaces a local report file, so choose its path deliberately. If you need structured records, the installed CLI also accepts the json format:
$ docker volume ls --format json
{"Driver":"local","Labels":"","Mountpoint":"/var/lib/docker/volumes/example-data/_data","Name":"example-data","Scope":"local"}
Treat mountpoints as operational data. They can disclose host layout, and they are not a promise that you should edit the directory directly. Use Docker's volume commands and the volume driver's documentation for further operations.
7. Verify a result before acting on it
Once a filter finds a candidate, repeat the name-only query and inspect the exact volume before any state-changing command:
$ docker volume ls --filter 'name=project' --quiet
project-db
$ docker volume inspect project-db
If the name-only output is empty, do not substitute a guessed directory or a similar name. If several names are returned, review each one. This small pause prevents a partial filter match from becoming an accidental operation on the wrong volume.
Done means
- You confirmed the installed Docker CLI and daemon access.
- You can list all volumes or names only without changing state.
- You can filter by name, driver, label and dangling status.
- You can distinguish an empty match from a command failure.
- You can format a report without parsing padded table columns.
- You have reviewed ownership and backups before considering removal or pruning.