How to copy multiple files from container to host using docker cp

Docker cp command supports to copy folder with all the contents inside a folder

docker cp -a container-id:/opt/tpa/logs/  /root/testing/

In the above example copying files from container folder /opt/tpa/logs to local machine /root/testing/ folder. Here all the files inside /logs/ will be copied to local. The trick here is using -a option along with docker cp


Run this inside the container:

dcp() {
  if [ "$#" -eq 1 ]; then
    printf "docker cp %q .\n" "$(hostname):$(readlink -e "$1")"
  else
    local archive="$(mktemp -t "export-XXXXX.tgz")"
    tar czf "$archive" "$@" --checkpoint=.52428800
    printf "docker exec %q cat %q | tar xvz -C .\n" "$(hostname)" "$archive"
  fi
}

Then select the files you want to copy out:

dcp /foo/metrics.csv*

It'll create an archive inside of the container and spit out a command for you to run. Run that command on the host.

e.g.

docker exec 1c75ed99fa42 cat /tmp/export-x9hg6.tgz | tar xvz -C .

Or, I guess you could do it without the temporary archive:

dcp() {
  if [ "$#" -eq 1 ]; then
    printf "docker cp %q .\n" "$(hostname):$(readlink -e "$1")"
  else
    printf "docker exec %q tar czC %q" "$(hostname)" "$PWD"
    printf " %q" "$@"
    printf " | tar xzvC .\n"
  fi
}

Will generate a command for you, like:

docker exec 1c75ed99fa42 tar czC /root .cache .zcompdump .zinit .zshrc .zshrc.d foo\ bar | tar xzvC .

You don't even need the alias then, it's just a convenience.


In fact your solution can make your aims just need a little change:

for f in $(docker exec -it SPSRS bash -c "ls /opt/tpa/logs/metrics.csv*"); do docker cp SPSRS:$f /root/metrices_testing/; done

->

for f in $(docker exec -it SPSRS bash -c "ls /opt/tpa/logs/metrics.csv*"); do docker cp SPSRS:`echo $f | sed 's/\r//g'` /root/metrices_testing/; done

This is because docker exec -it SPSRS bash -c "ls /opt/tpa/logs/metrics.csv*" will have \r in every matched string, so finally the cp can not find the files in container.

So, we use echo $f | sed 's/\r//g' to get rid of \r for every file name, this could make you work.


Docker cp still doesn't support wildcards. You can however use them in a Dockerfile in the following way:

COPY hom* /mydir/        # adds all files starting with "hom"
COPY hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

Reference: https://docs.docker.com/engine/reference/builder/#copy

Tags:

Docker

Cp