30

I want to update some container. For testing, I want to create a copy of the corresponding volume. Set up a new container for this new volume.

Is this as easy as doing cp -r volumeOld volumeNew?

Or do I have to pay attention to something?

MauriceNino
  • 6,214
  • 1
  • 23
  • 60
Ma Sch
  • 501
  • 1
  • 4
  • 8

5 Answers5

34

To clone docker volumes, you can transfer your files from one volume to another one. For that you have to manually create a new volume and then spin up a container to copy the contents.

Someone has already made a script for that, which you might use: https://github.com/gdiepen/docker-convenience-scripts/blob/master/docker_clone_volume.sh

If not, use the following commands (taken from the script):

# Supplement "old_volume" and "new_volume" for your real volume names

docker volume create --name new_volume

docker container run --rm -it \
           -v old_volume:/from \
           -v new_volume:/to \
           alpine ash -c "cd /from ; cp -av . /to"
MauriceNino
  • 6,214
  • 1
  • 23
  • 60
  • 6
    Take care. alpine's cp (busybox) does not preserve hard links (even with the -a option). Using the script/snippet mentioned above does not result in an identical volume. (I found out the hard way when cloning an infludb data volume). Using ubuntu instead of alpine fixes that: see https://github.com/harmv/docker-convenience-scripts/blob/master/docker_clone_volume.sh – harmv Feb 17 '23 at 08:02
33

On Linux it can be as easy as copying a directory. Docker keeps volumes in /var/lib/docker/volumes/<volume_name>, so you can simply copy contents of the source volume into a directory with another name:

# -a to preserve all file attributes (permissions, ownership, etc)
sudo cp -a /var/lib/docker/volumes/source_volume /var/lib/docker/volumes/target_volume
anemyte
  • 17,618
  • 1
  • 24
  • 45
  • 3
    This actually worked! I initially did a copy as a root user but without -p and some of the containers were failing. I redid it with -p and everything worked fine! Thanks. – KungFuPanda Jun 01 '22 at 07:38
  • you mean `-a` flag as mentioned in answer or `-p` ? @KungFuPanda – Yusuf Jul 02 '23 at 13:12
  • 1
    @Yusuf the answer mentioned `-rp` originally, but `-a` is better. – anemyte Jul 02 '23 at 13:14
  • @anemyte man of `cp` shows for `-a` as `Same as -pPR options. Preserves structure and attributes of files but not directory structure.` So `-a` includes `-p` . But i did not understood the part `but not directory structure` – Yusuf Jul 02 '23 at 13:16
  • I want to use this method for backup of docker volume, so i can use this command with location as something different place but on same machine, still it will preserve all permissions, etc while restoring back from that place to a new docker volume later, right ? @anemyte – Yusuf Jul 02 '23 at 13:19
  • 1
    @Yusuf `-a` should preserve everything: links, ownership, permissions, directories and structure. At least, that's what my cp (GNU coreutils) 9.3 does. – anemyte Jul 02 '23 at 13:24
7

Should you want to copy volumes managed by docker-compose, you'll also need to copy the specific labels when creating the new volume. Else docker-compose will throw something like Volume already exists but was not created by Docker Compose.

Extending on the solution by MauriceNino, these lines worked for me:

# Supplement "proj1_vol1" and "proj2_vol2" for your real volume names

docker volume inspect proj1_vol1  # Look at labels of old volume

docker volume create \
           --label com.docker.compose.project=proj2 \
           --label com.docker.compose.version=2.2.1 \
           --label com.docker.compose.volume=vol2 \
           proj2_vol2

docker container run --rm -it \
           -v proj1_vol1:/from \
           -v proj2_vol2:/to \
           alpine ash -c "cd /from ; cp -av . /to"

Btw, this also seems to be the only way to rename Docker volumes.

3

Try to clone the volume using the "Volumes Backup & Share" Docker extension.

See https://www.docker.com/blog/back-up-and-share-docker-volumes-with-this-extension/

Cristi B.
  • 31
  • 3
  • To create an archive file that can imported with this Docker extension: `tar -czvf volume-archive.tar.gz -C /var/lib/docker/volumes//_data .` – ABika Jul 24 '23 at 11:28
0

In my work I use this script to:

  • clone the container
  • clone all its volumes and copy contents from the old volumes to the new ones
  • run the new container (with an arbitrary new image)
  • reattach the new volumes to the new container at the same destinations as the old ones

However, the script makes some assumptions about the naming of the volumes, so please read the README instructions before applying it.