Copiar archivos del contenedor Docker al host


Estoy pensando en usar Docker para construir mis dependencias en un servidor de integración continua (CI), de modo que no tenga que instalar todos los tiempos de ejecución y bibliotecas en los propios agentes. Para lograr esto tendría que copiar los artefactos de construcción que se construyen dentro del contenedor de nuevo en el host.

¿Es eso posible?

Author: lospejos, 2014-02-26

13 answers

Para copiar un archivo desde un contenedor al host, puede usar el comando

docker cp <containerId>:/file/path/within/container /host/path/target

Aquí hay un ejemplo:

[jalal@goku scratch]$ sudo docker cp goofy_roentgen:/out_read.jpg .

Aquí goofy_roentgen es el nombre que obtuve del siguiente comando:

[jalal@goku scratch]$ sudo docker ps
[sudo] password for jalal:
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                            NAMES
1b4ad9311e93        bamos/openface      "/bin/bash"         33 minutes ago      Up 33 minutes       0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp   goofy_roentgen
 1671
Author: creack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-12 19:10:28

Monte un "volumen"y copie los artefactos allí:

mkdir artifacts
docker run -i -v ${PWD}/artifacts:/artifacts ubuntu:14.04 sh << COMMANDS
# ... build software here ...
cp <artifact> /artifacts
# ... copy more artifacts into `/artifacts` ...
COMMANDS

Luego, cuando la compilación termina y el contenedor ya no se está ejecutando, ya ha copiado los artefactos de la compilación en el directorio artifacts en el host.

EDITAR:

ADVERTENCIA: Al hacer esto, puede tener problemas con el id de usuario del usuario de docker que coincida con el id de usuario del usuario en ejecución actual. Es decir, los archivos en /artifacts se mostrarán como propiedad del usuario con el UID del usuario utilizado dentro del contenedor docker. Una forma de evitar esto puede ser usar el UID del usuario que llama:

docker run -i -v ${PWD}:/working_dir -w /working_dir -u $(id -u) \
    ubuntu:14.04 sh << COMMANDS
# Since $(id -u) owns /working_dir, you should be okay running commands here
# and having them work. Then copy stuff into /working_dir/artifacts .
COMMANDS
 59
Author: djhaskin987,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-23 16:08:49

Monte un volumen, copie los artefactos, ajuste el id del propietario y el id del grupo:

mkdir artifacts
docker run -i --rm -v ${PWD}/artifacts:/mnt/artifacts centos:6 /bin/bash << COMMANDS
ls -la > /mnt/artifacts/ls.txt
echo Changing owner from \$(id -u):\$(id -g) to $(id -u):$(id -u)
chown -R $(id -u):$(id -u) /mnt/artifacts
COMMANDS
 18
Author: Dimchansky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-30 15:28:52

Tldr;

$ docker run --rm -iv${PWD}:/host-volume my-image sh -s <<EOF
chown $(id -u):$(id -g) my-artifact.tar.xz
cp -a my-artifact.tar.xz /host-volume
EOF

Más...

docker run con un volumen de host, chown el artefacto, cp el artefacto al volumen de host:

$ docker build -t my-image - <<EOF
> FROM busybox
> WORKDIR /workdir
> RUN touch foo.txt bar.txt qux.txt
> EOF
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
 ---> 00f017a8c2a6
Step 2/3 : WORKDIR /workdir
 ---> Using cache
 ---> 36151d97f2c9
Step 3/3 : RUN touch foo.txt bar.txt qux.txt
 ---> Running in a657ed4f5cab
 ---> 4dd197569e44
Removing intermediate container a657ed4f5cab
Successfully built 4dd197569e44

$ docker run --rm -iv${PWD}:/host-volume my-image sh -s <<EOF
chown -v $(id -u):$(id -g) *.txt
cp -va *.txt /host-volume
EOF
changed ownership of '/host-volume/bar.txt' to 10335:11111
changed ownership of '/host-volume/qux.txt' to 10335:11111
changed ownership of '/host-volume/foo.txt' to 10335:11111
'bar.txt' -> '/host-volume/bar.txt'
'foo.txt' -> '/host-volume/foo.txt'
'qux.txt' -> '/host-volume/qux.txt'

$ ls -n
total 0
-rw-r--r-- 1 10335 11111 0 May  7 18:22 bar.txt
-rw-r--r-- 1 10335 11111 0 May  7 18:22 foo.txt
-rw-r--r-- 1 10335 11111 0 May  7 18:22 qux.txt

Este truco funciona porque la invocación chown dentro del heredoc toma $(id -u):$(id -g) valores desde fuera del contenedor en ejecución; es decir, el host acoplable.

Los beneficios sobre docker cp son:

  • usted no tiene que docker run --name su contenedor antes de
  • no tienes que docker container rm después de{[24]]}
 12
Author: rubicks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-12 17:34:15

Si no tiene un contenedor en ejecución, solo una imagen, y asumiendo que desea copiar solo un archivo de texto, podría hacer algo como esto:

docker run the-image cat path/to/container/file.txt > path/to/host/file.txt
 10
Author: cancerbero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-23 10:59:09

No necesita usar docker run

Puedes hacerlo con docker create

De los documentos El comando docker create crea una capa contenedor de escritura sobre la imagen especificada y la prepara para ejecutar el comando especificado. El ID del contenedor se imprime en STDOUT. Esto es similar a docker run-d, excepto que el contenedor nunca se inicia.

Entonces, puedes hacer

docker create -ti --name dummy IMAGE_NAME bash
docker cp dummy:/path/to/file /dest/to/file
docker rm -fv dummy

Aquí, nunca se inicia el contenedor. Eso me pareció beneficioso.

 8
Author: Ishan Bhatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-05 08:25:27

Estoy publicando esto para cualquiera que esté usando Docker para Mac. Esto es lo que funcionó para mí:

 $ mkdir mybackup # local directory on Mac

 $ docker run --rm --volumes-from <containerid> \
    -v `pwd`/mybackup:/backup \  
    busybox \                   
    cp /data/mydata.txt /backup 

Tenga en cuenta que cuando monte usando -v ese directorio backup se crea automáticamente.

Espero que esto sea útil para alguien algún día. :)

 6
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-17 08:10:44

La mayoría de las respuestas no indican que el contenedor debe ejecutarse antes de que docker cp funcione:

docker build -t IMAGE_TAG .
docker run -d IMAGE_TAG
CONTAINER_ID=$(docker ps -alq)
# If you do not know the exact file name, you'll need to run "ls"
# FILE=$(docker exec CONTAINER_ID sh -c "ls /path/*.zip")
docker cp $CONTAINER_ID:/path/to/file .
docker stop $CONTAINER_ID
 4
Author: cmcginty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-23 10:59:46

Como una solución más general, hay un plugin CloudBees para Jenkins para construir dentro de un contenedor Docker. Puede seleccionar una imagen para usar de un registro de Docker o definir un archivo de Docker para compilar y usar.

Montará el espacio de trabajo en el contenedor como un volumen (con el usuario apropiado), lo establecerá como su directorio de trabajo, hará los comandos que solicite (dentro del contenedor). También puede utilizar el complemento docker-workflow (si prefiere el código sobre la interfaz de usuario) para hacer esto, con el imagen.inside() {} comando.

Básicamente todo esto, horneado en su servidor CI/CD y algo más.

 3
Author: BobMcGee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-19 19:03:34
 2
Author: shuaihanhungry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-16 02:55:20

Si solo desea extraer un archivo de una imagen (en lugar de un contenedor en ejecución) puede hacer esto:

docker run --rm <image> cat <source> > <local_dest>

Esto abrirá el contenedor, escribirá el nuevo archivo y luego eliminará el contenedor. Un inconveniente, sin embargo, es que los permisos de archivo y la fecha de modificación no se conservarán.

 1
Author: s g,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-30 04:06:37

Cree una ruta donde desea copiar el archivo y luego use:

docker run -d -v hostpath:dockerimag
 0
Author: Chandra Pal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-23 11:00:11

Cree un directorio de datos en el sistema host (fuera del contenedor) y monte esto en un directorio visible desde el interior del contenedor. Esto coloca los archivos en una ubicación conocida en el sistema host, y hace que sea fácil para las herramientas y aplicaciones del sistema host acceder a los archivos

docker run -d -v /path/to/Local_host_dir:/path/to/docker_dir docker_image:tag
 -1
Author: Innocent Anigbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-20 10:36:34