Docker volume: rename or copy operation
Asked Answered
U

2

16

As per documentation Docker volumes are advertised this way:

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure and OS of the host machine, volumes are completely managed by Docker.

But if they are so good, why there are no operations to manage them like: copy, rename?

the command:

docker volume --help

gives only these options:

Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

Documentation also states no other commands, nor any workarounds for having the copy or rename functionality.

I would like to rename currently existing volume and create another (blank) in place of the originally named volume and populate it with the new data for test.

After doing my test I may want (or not) to remove the newly created volume and rename the other one to its previous (original) name to restore the volume setup as it was before.

I would like to not create a backup of the original volume that I want to rename. Renaming is good enough for me and much faster than creating the backup and restoring form it.

Editing the docker-compose file and changing the name of the volume there is something I would like to avoid as well.

Is there any workaround that can work for renaming of a volume?

Can low level manual management from the shell targeting the Docker Root Dir: /var/lib/docker and volumes sub-dir be a solution or that approach may lead to some docker demon data inconsistency?

Unmade answered 20/7, 2022 at 14:23 Comment(0)
A
11

Not really the answer but I'll post this copy example because I couldn't find any before and searching for it took me to this question.

Docker suggest --volumes-from for backup purposes here.
For offline migration (stopped container) I don't see the point in using --volumes-from. So I just used a middle container with both volumes mounted and a copy command.

To finish off the migration a new container can use the new volume

Here's a quick test

Prepare a volume prova

docker run --name myname -d -v prova:/usr/share/nginx/html nginx:latest
docker exec myname touch /usr/share/nginx/html/added_file
docker stop myname

Verify the volume has nginx data + our file added_file

sudo ls /var/lib/docker/volumes/prova/_data

Output:

50x.html  added_file  index.html

Migrate the data to volume prova2

docker run --rm \
  -v prova:/original \
  -v prova2:/migration \
  ubuntu:latest \
  bash -c "cp -R /original/* /migration/"

Verify the new volume has the same data

sudo ls /var/lib/docker/volumes/prova2/_data

Output:

50x.html  added_file  index.html

Run a new container with the migrated volume:

docker run --name copyname -d -v prova2:/user/share/nginx/html nginx:latest

Verify the new container sees the migrated data at the original volume moint point:

docker exec copyname ls -al /user/share/nginx/html
Aught answered 22/7, 2022 at 14:59 Comment(5)
why not just copy the folders directly from /var/lib/docker/volumes/prova/_data to /var/lib/docker/volumes/prova2/_data , instead of creating intermediate containers?Kellda
I will have a closer look at your solution later, good that you had some steps for verification. I appreciate giving commands with their expected output.Unmade
I have the same question as @Myoch. Is there any important reason to use the temporary container to copy the contents of a volume, other than for hiding the internal structure (/var/lib/docker/volumes/...) of Docker volumes?Spadix
Though I'm not the poster of the answer, I sorta feel like it might be related to permissions, to ensure that it's consistent. Other than that, I think it does seem to me to make sense to at least test that it works just fine across all platforms.Shoulder
Checking in after some testing. I copied the files from one volume to the other volume from the host machine and so far haven't run into any issues. The only problem in my case was that I tried to copy a .sock file, which stalled indefinitely when trying to copy; I skipped that file in the next attempt, it finished copying successfully, and then I tested it out to find that everything was there and working. This was on Windows, though, so others may need to test if their environment doesn't match mine.Shoulder
P
6

For next searchers, I made a script that can do a copy of volume by @Lennonry example. Here it is https://github.com/KOYU-Tech/docker-volume-copy

Script itself for history:

#!/bin/bash

if (( $# < 2 )); then
    echo ""
    echo "No arguments provided"
    echo "Use command example:"
    echo "./dcv.sh OLD_VOLUME_NAME NEW_VOLUME_NAME"
    echo ""
    exit 1
fi

OLD_VOLUME_NAME="$1"
NEW_VOLUME_NAME="$2"

echo "== From '$OLD_VOLUME_NAME' to '$NEW_VOLUME_NAME' =="

function isVolumeExists {
    local isOldExists=$(docker volume inspect "$1" 2>/dev/null | grep '"Name":')
    local isOldExists=${isOldExists#*'"Name": "'}
    local isOldExists=${isOldExists%'",'}
    local isOldExists=${isOldExists##*( )}
    if [[ "$isOldExists" == "$1" ]]; then
        return 1
    else
        return 0
    fi
}


# check if old volume exists
isVolumeExists ${OLD_VOLUME_NAME}
if [[ "$?" -eq 0 ]]; then
    echo "Volume $OLD_VOLUME_NAME doesn't exist"
    exit 2
fi

# check if new volume exists
isVolumeExists ${NEW_VOLUME_NAME}
if [[ "$?" -eq 0 ]]; then
    echo "creating '$NEW_VOLUME_NAME' ..."
    docker volume create ${NEW_VOLUME_NAME} 2>/dev/null 1>/dev/null
    isVolumeExists ${NEW_VOLUME_NAME}
    if [[ "$?" -eq 0 ]]; then
        echo "Cannot create new volume"
        exit 3
    else
        echo "OK"
    fi
fi

# most important part, data migration
docker run --rm --volume ${OLD_VOLUME_NAME}:/source --volume ${NEW_VOLUME_NAME}:/destination ubuntu:latest bash -c "echo 'copying volume ...'; cp -Rp /source/* /destination/"

if [[ "$?" -eq 0 ]]; then
    echo "Done successfuly 🎉"
else
    echo "Some error occured 😭"
fi
Personable answered 29/12, 2022 at 16:48 Comment(2)
Thank you for the effort you put. I liked you took care for a user experience and provided an instruction how to use your code echo "No arguments provided" .... The 2>/dev/null in the docker volume create ${NEW_VOLUME_NAME} 2>/dev/null hides potentially a valuable info in case something goes wrong. I would remove the 2>/dev/null. The line echo "Some error occured has UTF emoji but I would suggest sticking to ASCII only. Maybe colorized if you like? If Some error occured then I miss there an exit 1 or other nonzero code.Unmade
Also would be great to add -p option to cp command to preserve files ownership and rights. So the full copy command would be cp -Rp /source/* /destination/Equi

© 2022 - 2024 — McMap. All rights reserved.