By default, Docker containers are ephemeral, which means that any data generated or modified within a container is lost when the container is stopped or removed. Docker volumes allow you to create persistent storage outside the container, which can be accessed and shared by multiple containers.
Avatar
Latest posts by Surender Kumar (see all)

You can work with two types of volumes in Docker:

Bind mounts: These are files or directories on the host system that are mounted into a Docker container. This means that any changes made to the volume from within the container will be reflected on the host filesystem, and vice versa. Files and folders are referenced by their absolute paths on the host machine.

Named volumes: Sometimes, this type of volume is called a Docker volume, or just a volume. Docker creates and manages named volumes to provide persistent storage for containers. They are not directly tied to the host machine.

Check out this 4sysops post to learn about named volumes in greater detail.

Here, we focus on moving a named volume from one host to another. For the purposes of demonstration, I will move a volume containing the custom images of my private docker registry from a source host (srv1) to a new host (srv2) running in Proxmox.

Back up a Docker volume

I will first ssh into my source Docker host (srv1) and view the custom Docker images stored in the private Docker registry. To do so, run the following commands:

sudo docker image ls
curl -kL https://registry.testlab.local/v2/_catalog
View the custom images stored in a private Docker registry

View the custom images stored in a private Docker registry

As you can see in the screenshot, I have two custom Docker images (awesome_app and nginx). They are stored in a Docker volume (docker_repo). By the end of this tutorial, these images will reside on our new Docker host (srv2).

Backing up a bind mount is fairly easy, since it is just a directory on a Docker host. But to back up a Docker-managed volume, you first need to perform a few checks. First, run the following command to inspect the container you are going to back up (the container name in our case is registry).

sudo docker inspect registry
Inspect the Docker container to view the mounted volumes

Inspect the Docker container to view the mounted volumes

Once we know the name of the Docker volume, run the following command:

sudo docker run --rm \
--volumes-from registry \
--volume $(pwd):/docker_backup \
busybox tar -cvzf /docker_backup/registry.tgz docker_repo
Back up a Docker volume by running a temporary container and tar command

Back up a Docker volume by running a temporary container and tar command

The above command spins a temporary container with a busybox image, mounts the volumes of the registry container with the help of the --volumes-from option, mounts the current working directory from the host to the /docker_backup path in a temporary container, and finally, runs the tar command to compress the contents of the docker_repo volume. The --rm flag allows the container to clean itself once the tar command is successful. In a nutshell, this command creates a registry.tgz file in our current working directory on the source Docker host (srv1) containing all the files from the docker_repo volume.

Viewing the backup file on the source Docker host

Viewing the backup file on the source Docker host

We can now transfer this backup file to the target Docker host (srv2) using scp, as shown in the following command:

scp registry.tgz surender@srv2.testlab.local:/home/surender/
Copying the backup file to the target Docker host using scp

Copying the backup file to the target Docker host using scp

Restoring a Docker volume

I will now ssh into the target Docker host. Let's first check whether the registry.tgz file, which we transferred from the other Docker host, is there. I will also verify that there is no existing volume named docker_repo.

Checking the registry backup file and Docker volumes on the target host

Checking the registry backup file and Docker volumes on the target host

Now, I run the following command to run a private Docker registry container on the new Docker host (srv2):

sudo docker run --detach \
  --restart=always \
  --name registry \
  --mount type=volume,source=docker_repo,target=/docker_repo \
  --env REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/docker_repo \
  --publish 5000:5000 \
  registry
Run a private Docker registry container on a new host

Run a private Docker registry container on a new host

I discussed this command in detail in my previous article. In a nutshell, this command creates a new local docker volume (docker_repo) and then launches a private Docker registry container with the docker_repo mounted volume.

I now have to change the A record of the registry.testlab.local subdomain to my new Docker host (srv2). At this stage, if we send a curl request to our private Docker registry, you will notice that there is no custom Docker image available yet.

ping registry.testlab.local
curl -kL https://registry.testlab.local/v2/_catalog
Sending a curl request to a private Docker registry to view custom images

Sending a curl request to a private Docker registry to view custom images

To restore the volume that we backed up from the other Docker host (srv1), run the following command:

sudo docker run --rm \
--volumes-from registry \
--volume $(pwd):/docker_backup \
busybox sh -c "cd /docker_repo && tar -xvf /docker_backup/registry.tgz --strip 1"
Restoring the Docker volume from backup by running a temporary container

Restoring the Docker volume from backup by running a temporary container

This command launches a temporary container with a busybox image, uses the --volumes-from option to mount the registry container's volume (i.e., docker_repo), mounts the current working directory from the host to the /docker_backup path inside the container, and then runs the tar command to extract the registry.tgz file into the /docker_repo directory inside the container. In the end, we get all the contents extracted into the docker_repo volume on the new host, and the temporary container cleans itself once the extraction is finished.

Now repeat the curl command. This time, you will see two custom images (awesome_app and nginx) in response:

curl -kL https://registry.testlab.local/v2/_catalog
Sending a curl request to a private Docker registry after restoring to view custom images

Sending a curl request to a private Docker registry after restoring to view custom images

Since Docker-managed volumes are stored under the /var/lib/docker/volumes/ directory in Linux, run the following command to verify that everything was restored exactly where it is supposed to be:

sudo tree /var/lib/docker/volumes/docker_repo/ -L 7
Verifying the contents of the Docker volume after restore

Verifying the contents of the Docker volume after restore

You can now run the Docker pull command and start using your custom images from the private Docker registry running on the new host.

Subscribe to 4sysops newsletter!

sudo docker pull registry.testlab.local/awesome_app
sudo docker image ls
Pulling the Docker image from the private Docker registry running on the new host

Pulling the Docker image from the private Docker registry running on the new host

That was all for this guide. You just learned how to move a Docker volume from one host to another.

avatar
0 Comments

Leave a reply

Please enclose code in pre tags: <pre></pre>

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account