Browsing all Docker Volumes at Once
While using docker, you may find you want to quickly inspect the contents of one or more volumes, for example to figure out what’s going on inside it, back up data, tail log files, rearrange files, or add a file from the host system. Here’s a handy one-liner that makes all that quite simple, followed by an explanation and some improvements that are possible and easy:
1 | docker run --rm -ti $(docker volume ls --format='-v {{.Name}}:/vols/{{.Name}}') -v $HOME:/host_home bash |
This will mount all your volumes as directories named after each volume, in the /vols directory of the container it will launch, and will mount the $HOME
directory of your host system into /host_home
on the container, which makes it easy to copy files between host and volumes.
An Explanation
Let’s build up that command step by step. First we list all the volumes on the system:
1 | $ docker volume ls |
We want to get just the names of these volumes, and mount those into a docker container. Since the typical syntax for mounting a volume into a container is docker run -v <Volume Name 1>:<Mount Path 1> -v <Volume Name 2>:<Mount Path 2> <Image name>
(etc.), we will write a command that generates that list of volume mounts, then include that in the docker run
command using command substitution.
If we had volumes called FooVolume
and BarVolume
, we’d want our docker run
flags to look something like -v FooVolume:/vols/FooVolume -v BarVolume:/vols/FooVolume
. Luckily, most docker commands take a --format
argument that lets us tweak the output to look exactly how we want it, so we can get that format using this syntax:
1 | $ docker volume ls --format='-v {{.Name}}:/vols/{{.Name}}' |
Then we can just add a -v $HOME:/host_home
to mount the host system’s home folder (aka ~
) into the container for easy copying between the host and the volumes. This can be left out if you don’t need this functionality, but I like to add it so there’s just one common command I use every time I’m browsing my volumes.
This gives us all the pieces we need to start browsing our volumes. We use command substitution to include all the volume mount flags, and -it
so that our shell is interactive:
1 | docker run --rm -ti $(docker volume ls --format='-v {{.Name}}:/vols/{{.Name}}') -v $HOME:/host_home bash |
Installing our favorite utilities to make life easier
We could use the command above and call it a day, but there are several utilities Iike to have access to when I’m messing around with my volumes, such as ncdu (for quickly viewing directory sizes and the larges files), tree (for viewing all the files in a directory at a glance), vim (for file editing), and zsh with Oh My Zsh (just shell personal preference!).
We can make our own docker image to use which has all these things, or whatever tools you prefer, installed. Create a new directory wherever you keep projects:
1 | mkdir data-volume-explorer |
and create a Dockerfile that sets up your environment how you like it. Here’s my current Dockerfile:
1 | FROM alpine:latest |
This copies in my .zshrc
file as well, which I won’t include here, but does contain the following lines to put a yellow “Docker Volumes” in my prompt (so I remember that I’m in a container and not on my host system) and show all the volume names right when the container starts (since otherwise I would run ls
right away anyway):
1 | PS1="$(tput setaf 3)Docker Volumes $(tput sgr0)$PS1" |
Once you have your Dockerfile in good condition, build and tag it:
1 | docker build -t docker-volume-explorer . |
and now you can use it as your docker image to run instead of bash
:
1 | docker run --rm -ti $(docker volume ls --format='-v {{.Name}}:/vols/{{.Name}}') -v $HOME:/host_home docker-volume-explorer |