If I create a volume with:
docker volume create --name test-volume
I would like to then copy example.cfg into the volume. However, docker cp works with containers, not volumes.
Right now, I need to create a container that mounts the volume, copy the file in, then remove the container. Alternatively, I can inspect the volume and modify the filesystem directly. Is there a better way?
That's the way to do it. For configuration files, you could consider using a bind-mount, or perhaps a volume driver that allows mounting configuration as a volume https://docs.docker.com/engine/extend/plugins/#/volume-plugins
I'm closing this issue, because this is a question, not a bug report, but feel free to continue the discussion
Thanks for the quick reply. Has there been a consensus decision not to support "copy into volume", or is this something that could be requested as a feature? If there has been a decision, what was the rationale?
Oh, yes, there is an open feature request, but it hasn't been decided on yet; see https://github.com/docker/docker/issues/18718.
Perfect, thank you.
Do you want to copy a file to a docker volume, but the volume doesn't have a container? I'll tell you how I do it.
Unfortunately, you do need a container. But, this is actually the lightest-weight method I have found so far.
docker run to start a dummy light-weight container and mount your volume.tail -f /dev/null.-d option to _detatch_ and leave the dummy container running so that you can _reuse your existing shell_ to enter the next command. (which will be the docker cp command -- see step 2 below).--rm so that when you stop the dummy container it will get removed automatically. This is a temporary container, so using automatic cleanup is a good habit and will prevent leaving a forgotten dummy container lying around.-v to mount the volume into the file system of the container. Choose any path that doesn't conflict with something in alpine. e.g.: /root--name option to give the container a reasonable name to be used in steps 2 and 3 below. e.g.: dummydocker cp to copy the file into the container at the location you mounted the volume. In the example below, the file c:\myfolder\myfile.txt is copied into the volume.docker stop to stop the dummy container. This will also cause docker to remove the container because you used the --rm option.docker run -d --rm --name dummy -v myvolume:/root alpine tail -f /dev/null
docker cp c:\myfolder\myfile.txt dummy:/root/myfile.txt
docker stop dummy
You can also copy the other way (from the volume to the local file system).
docker cp dummy:/root/myfile.txt c:\myfolder\myfile.txt
_If there's a better way, I'd love to know what it is!_
There's no need to _start_ the container, just _creating_ a container is enough;
docker container create --name dummy -v myvolume:/root hello-world
docker cp c:\myfolder\myfile.txt dummy:/root/myfile.txt
docker rm dummy
Here's a one-liner that copies myfile.txt from current directory to my_volume:
docker run --rm -v $PWD:/source -v my_volume:/dest -w /source alpine cp myfile.txt /dest
@thaJeztah That's cool, thanks!
Now I'm wondering, is there an image that is lighter weight than hello-world? I can't just create a container running scratch.
So, I used the following Dockerfile to create a _nothing_ image.
FROM scratch
CMD
docker build -t nothing .
Now my steps are:
docker container create --name dummy -v myvolume:/root nothing
docker cp c:\myfolder\myfile.txt dummy:/root/myfile.txt
docker rm dummy
@wyckster
https://hub.docker.com/r/tianon/true/ is pretty light.
125 bytes
Here is my convenience script:
docker-volume-cp
#!/bin/bash
SOURCE=$1
DEST=$2
SOURCE_ARR=(${SOURCE//:/ })
DEST_ARR=(${DEST//:/ })
if [[ ${#SOURCE_ARR[@]} -eq 2 && ${#DEST_ARR[@]} -eq 1 ]]; then
VOL=${SOURCE_ARR[0]}
VOL_PATH=${SOURCE_ARR[1]}
HOST_PATH=${DEST_ARR[0]}
docker container create --name docker_volume_cp -v $VOL:/volume hello-world
CMD="docker cp docker_volume_cp:/volume/$VOL_PATH $HOST_PATH"
#echo "$CMD"
$CMD
docker rm docker_volume_cp
elif [[ ${#SOURCE_ARR[@]} -eq 1 && ${#DEST_ARR[@]} -eq 2 ]]; then
VOL=${DEST_ARR[0]}
VOL_PATH=${DEST_ARR[1]}
HOST_PATH=${SOURCE_ARR[0]}
docker container create --name docker_volume_cp -v $VOL:/volume hello-world
CMD="docker cp $HOST_PATH docker_volume_cp:/volume/$VOL_PATH"
#echo "$CMD"
$CMD
docker rm docker_volume_cp
else
echo "Usage:"
echo " volume --> host: $0 VOLUME:VOL_PATH HOST_PATH"
echo " host --> volume: $0 HOST_PATH VOLUME:VOL_PATH"
fi
Explanation:
Examples:
./docker-volume-cp myvolume:. myvolume_dir (copy all contents of volume "myvolume" into a host directory "myvolume_dir")./docker-volume-cp myvolume_dir/. myvolume_copy:. (copy all contents of host directory "myvolume_dir" into volume "myvolume_copy", which is created if it does not already exist)Here's a one-liner that copies
myfile.txtfrom current directory tomy_volume:
docker run --rm -v $PWD:/source -v my_volume:/dest -w /source alpine cp myfile.txt /dest
@mvasin
How do copy from container to host in one line?
Most helpful comment
There's no need to _start_ the container, just _creating_ a container is enough;