What is the right way to add data to an existing named volume in Docker?

Docker

Docker Problem Overview


I was using Docker in the old way, with a volume container:

docker run -d --name jenkins-data jenkins:tag echo "data-only container for Jenkins"

But now I changed to the new way by creating a named volume:

 docker volume create --name my-jenkins-volume 

I bound this new volume to a new Jenkins container. The only thing I've left is a folder in which I have the /var/jenkins_home of my previous jenkins container. (by using docker cp) Now I want to fill my new named volume with the content of that folder.

Can I just copy the content of that folder to /var/lib/jenkins/volume/my-jenkins-volume/_data?

Docker Solutions


Solution 1 - Docker

You can certainly copy data directly into /var/lib/docker/volumes/my-jenkins-volume/_data, but by doing this you are:

  • Relying on physical access to the docker host. This technique won't work if you're interacting with a remote docker api.

  • Relying on a particular aspect of the volume implementation would could change in the future, breaking any processes you have that rely on it.

I think you are better off relying on things you can accomplish using the docker api, via the command line client. The easiest solution is probably just to use a helper container, something like:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper

Solution 2 - Docker

You don't need to start some container to add data to already existing named volume, just create a container and copy data there:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp

Solution 3 - Docker

You can reduce the accepted answer to one line using, e.g.

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data

Solution 4 - Docker

Here are steps for copying contents of ~/data to docker volume named my-vol

Step 1. Attach the volume to a "temporary" container. For that run in terminal this command :

docker run --rm -it --name alpine --mount type=volume,source=my-vol,target=/data alpine

Step 2. Copy contents of ~/data into my-vol . For that run this commands in new terminal window :

cd ~/data docker cp . alpine:/data

This will copy contents of ~/data into my-vol volume. After copy exit the temporary container.

Solution 5 - Docker

You can add this BASH function to your .bashrc to copy files to a existing Docker volume without running a container

# Usage: copy-to-docker-volume SRC_PATH DEST_VOLUME_NAME [DEST_PATH]
copy-to-docker-volume() {
  SRC_PATH=$1
  DEST_VOLUME_NAME=$2
  DEST_PATH="${3:-}"
  # create smallest Docker image possible
  echo -e 'FROM scratch\nLABEL empty=""' | docker build -t empty -
  # create temporary container to be able to mount volume
  CONTAINER_ID=$(docker container create -v my-volume:/data empty cmd)
  # copy files to volume
  docker cp "${SRC_PATH}" "${CONTAINER_ID}":"/data/${DEST_PATH}"
  # remove temporary container
  docker rm "${CONTAINER_ID}"
}

Example

# create volume as destination
docker volume create my-volume
# create directory to copy
mkdir my-dir
echo "hello file1" > my-dir/my-file-1
# copy directory to volume
copy-to-docker-volume my-dir my-volume
# list directory on volume
docker run --rm -it -v my-volume:/data busybox ls -la /data/my-dir
# show file content on volume
docker run --rm -it -v my-volume:/data busybox cat /data/my-dir/my-file-1

# create another file to copy
echo "hello file2" > my-file-2
# copy file to directory on volume
copy-to-docker-volume my-file-2 my-volume my-dir
# list (updated) directory on volume
docker run --rm -it -v my-volume:/data busybox ls -la /data/my-dir
# check volume content
docker run --rm -it -v my-volume:/data busybox cat /data/my-dir/my-file-2

Solution 6 - Docker

If you don't want to create a docker and you can access as privileged user to , simply do (on Linux systems):

docker volume create my_named_volume
sudo cp -p . /var/lib/docker/volumes/my_named_volume/_data/

Furthermore, it also allows you to access data in docker runtime or also with docker containers stopped.

Solution 7 - Docker

If you don't want to create a temp helper container on windows docker desktop (backed by wsl2) then copy the files to below location

\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\my-volume\_data

here my-volume is the name of your named volume. browse the above path from address bar in your file explorer. This is a internal network created by wsl in windows.

enter image description here

Note: it might be better to use docker API like mentioned by larsks, but I have not faced any issues on windows.

Similarly on linux files can be copied to

/var/lib/docker/volumes/my-volume/_data/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDenCowboyView Question on Stackoverflow
Solution 1 - DockerlarsksView Answer on Stackoverflow
Solution 2 - DockerDmytro MelnychukView Answer on Stackoverflow
Solution 3 - DockerheaddabView Answer on Stackoverflow
Solution 4 - DockerNamig HajiyevView Answer on Stackoverflow
Solution 5 - DockermaiermicView Answer on Stackoverflow
Solution 6 - DockerAlejandro GaleraView Answer on Stackoverflow
Solution 7 - Dockerns94View Answer on Stackoverflow