docker-container tag - Copiando archivos del contenedor Docker al host




hub registry (13)

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, necesitaría copiar los artefactos de compilación que se construyen dentro del contenedor de nuevo en el host.

¿Es eso posible?


Answers

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

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

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

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

Aquí hay un ejemplo:

[[email protected] scratch]$ sudo docker cp goofy_roentgen:/out_read.jpg .

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

[[email protected] 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

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 los valores $(id -u):$(id -g) desde fuera del contenedor en ejecución; es decir, el host docker.

Los beneficios sobre docker cp son:

  • no tienes que docker run --name tu contenedor antes
  • no tienes que docker container rm después de

Cree un directorio de datos en el sistema host (fuera del contenedor) y móntelo en un directorio visible desde dentro del contenedor. Esto coloca los archivos en una ubicación conocida en el sistema host, y facilita que las herramientas y aplicaciones en el sistema host accedan a los archivos.

docker run -d -v /path/to/Local_host_dir:/path/to/docker_dir docker_image:tag

Monte un volumen, copie los artefactos, ajuste la identificación del propietario y la identificación 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

Utilicé PowerShell (Admin) con este comando.

docker cp {container id}:{container path}/error.html  C:\\error.html

Ejemplo

docker cp ff3a6608467d:/var/www/app/error.html  C:\\error.html

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

Montará el espacio de trabajo en el contenedor como un volumen (con el usuario adecuado), lo configurará como su directorio de trabajo, y ejecutará los comandos que solicite (dentro del contenedor). También puede usar el complemento de flujo de trabajo de la ventana acoplable (si prefiere el código sobre la interfaz de usuario) para hacer esto, con el comando image.inside () {}.

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


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 finaliza la compilación y el contenedor ya no se ejecuta, ya ha copiado los artefactos de la compilación en el directorio de artifacts en el host.

EDITAR:

CAVEAT: Al hacer esto, puede tener problemas con la identificación del usuario de la ventana acoplable que coincide con la identificación del usuario actual. Es decir, los archivos /artifacts se mostrarán como propiedad del usuario con el UID del usuario utilizado dentro del contenedor de la ventana acoplable. 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

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 de backup se crea automáticamente.

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


No es necesario utilizar la docker run

Puedes hacerlo con docker create

Desde la documentación El comando docker create crea una capa de contenedor grabable sobre la imagen especificada y la prepara para ejecutar el comando especificado. La ID del contenedor se imprime a continuación. Esto es similar a la ejecución de la ventana acoplable -d, excepto que el contenedor nunca se inicia.

Entonces tu 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 empiezas el contenedor. Eso me pareció beneficioso.


Crea una ruta donde quieras copiar el archivo y luego usa:

docker run -d -v hostpath:dockerimag

Si no tiene un contenedor en ejecución, solo una imagen, y suponiendo 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

Vagrant-lxc es un complemento para Vagrant que te permite usar LXC para aprovisionar Vagrant. No tiene todas las características que tiene la VM virtual predeterminada (VirtualBox) pero debería permitirle una mayor flexibilidad que los contenedores docker. Hay un video en el enlace que muestra sus capacidades que vale la pena ver.





docker docker-container file-copying