Pregunta

Estoy pensando en usar Docker para crear 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 crean dentro del contenedor nuevamente en el host.¿Es eso posible?

¿Fue útil?

Solución

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:

$ sudo docker cp goofy_roentgen:/out_read.jpg .

aquí goofy_roentgen es el nombre del contenedor que obtuve del siguiente comando:

$ sudo docker ps

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

También puede usar (parte de) la ID de contenedor .El siguiente comando es equivalente a la primera

$ sudo docker cp 1b4a:/out_read.jpg .

Otros consejos

No necesitas usar docker run

Puedes hacerlo con docker create

De los documentosEl comando docker create crea una capa contenedora que se puede escribir sobre la imagen especificada y la prepara para ejecutar el comando especificado.Luego, la 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 -f dummy

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

Monte un "volumen" y copie los artefactos en 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 los acabados de compilación y el contenedor ya no funcionan, ya ha copiado los artefactos de la construcción en el directorio de artifacts en el host.

Editar

advertencia: Cuando hace esto, puede tener problemas con el ID de usuario del usuario de Docker que coincide con el ID de usuario del usuario actual.Es decir, los archivos en /artifacts se mostrarán como propiedad del usuario con la UID del usuario que se usa dentro del contenedor de Docker.Una forma de evitar esto puede ser usar el UID del usuario de llamadas:

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

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

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

Descripción

docker run con un volumen de host, chown el artefacto, cp el artefacto al volumen 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 el chown invocación dentro del heredoc las tomas $(id -u):$(id -g) valores desde fuera del contenedor en ejecución;es decir, el host de la ventana acoplable.

Los beneficios son:

  • no tienes que hacerlo docker container run --name o docker container create --name antes
  • no tienes que hacerlo docker container rm después

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

docker run the-image cat path/to/container/file.txt > path/to/host/file.txt

La mayoría de las respuestas no indican que el contenedor deba ejecutarse antes docker cp trabajará:

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

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 monto usando -v eso backup El directorio se crea automáticamente.

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

Como una solución más general, Hay unPlugin de Cloudbees para Jenkins para construir dentro de un contenedor de Docker .Puede seleccionar una imagen para usar desde un registro DOCER o definir un archivo DOCER para construir y usar.

Montará el espacio de trabajo en el contenedor como un volumen (con el usuario apropiado), configúrelo como su directorio de trabajo, haga cualquier comando que solicite (dentro del contenedor). También puede usar el complemento Docker-Workflow (si prefiere código sobre UI) para hacer esto, con el comando image.inside () {}.

básicamente todo esto, horneado en su servidor CI / CD y luego algunos.

Si solo desea presionar 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, luego retire el contenedor.Sin embargo, un inconveniente es que los permisos de archivos y la fecha modificada no se conservarán.

Usé 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

Con el lanzamiento de Docker 19.03, puede omitir la creación del contenedor e incluso la creación de una imagen.Hay una opción con compilaciones basadas en BuildKit para cambiar el destino de salida.Puede usar esto para escribir los resultados de la compilación en su directorio local en lugar de en una imagen.P.ej.aquí hay una compilación de un binario go:

$ ls
Dockerfile  go.mod  main.go

$ cat Dockerfile
FROM golang:1.12-alpine as dev
RUN apk add --no-cache git ca-certificates
RUN adduser -D appuser
WORKDIR /src
COPY . /src/
CMD CGO_ENABLED=0 go build -o app . && ./app

FROM dev as build
RUN CGO_ENABLED=0 go build -o app .
USER appuser
CMD [ "./app" ]

FROM scratch as release
COPY --from=build /etc/passwd /etc/group /etc/
COPY --from=build /src/app /app
USER appuser
CMD [ "/app" ]

FROM scratch as artifact
COPY --from=build /src/app /app

FROM release

A partir del Dockerfile anterior, estoy construyendo el artifact etapa que solo incluye los archivos que quiero exportar.Y el recién introducido --output flag me permite escribirlos en un directorio local en lugar de en una imagen.Esto debe realizarse con el motor BuildKit que se envía con 19.03:

$ DOCKER_BUILDKIT=1 docker build --target artifact --output type=local,dest=. .
[+] Building 43.5s (12/12) FINISHED
 => [internal] load build definition from Dockerfile                                                                              0.7s
 => => transferring dockerfile: 572B                                                                                              0.0s
 => [internal] load .dockerignore                                                                                                 0.5s
 => => transferring context: 2B                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/golang:1.12-alpine                                                             0.9s
 => [dev 1/5] FROM docker.io/library/golang:1.12-alpine@sha256:50deab916cce57a792cd88af3479d127a9ec571692a1a9c22109532c0d0499a0  22.5s
 => => resolve docker.io/library/golang:1.12-alpine@sha256:50deab916cce57a792cd88af3479d127a9ec571692a1a9c22109532c0d0499a0       0.0s
 => => sha256:1ec62c064901392a6722bb47a377c01a381f4482b1ce094b6d28682b6b6279fd 155B / 155B                                        0.3s
 => => sha256:50deab916cce57a792cd88af3479d127a9ec571692a1a9c22109532c0d0499a0 1.65kB / 1.65kB                                    0.0s
 => => sha256:2ecd820bec717ec5a8cdc2a1ae04887ed9b46c996f515abc481cac43a12628da 1.36kB / 1.36kB                                    0.0s
 => => sha256:6a17089e5a3afc489e5b6c118cd46eda66b2d5361f309d8d4b0dcac268a47b13 3.81kB / 3.81kB                                    0.0s
 => => sha256:89d9c30c1d48bac627e5c6cb0d1ed1eec28e7dbdfbcc04712e4c79c0f83faf17 2.79MB / 2.79MB                                    0.6s
 => => sha256:8ef94372a977c02d425f12c8cbda5416e372b7a869a6c2b20342c589dba3eae5 301.72kB / 301.72kB                                0.4s
 => => sha256:025f14a3d97f92c07a07446e7ea8933b86068d00da9e252cf3277e9347b6fe69 125.33MB / 125.33MB                               13.7s
 => => sha256:7047deb9704134ff71c99791be3f6474bb45bc3971dde9257ef9186d7cb156db 125B / 125B                                        0.8s
 => => extracting sha256:89d9c30c1d48bac627e5c6cb0d1ed1eec28e7dbdfbcc04712e4c79c0f83faf17                                         0.2s
 => => extracting sha256:8ef94372a977c02d425f12c8cbda5416e372b7a869a6c2b20342c589dba3eae5                                         0.1s
 => => extracting sha256:1ec62c064901392a6722bb47a377c01a381f4482b1ce094b6d28682b6b6279fd                                         0.0s
 => => extracting sha256:025f14a3d97f92c07a07446e7ea8933b86068d00da9e252cf3277e9347b6fe69                                         5.2s
 => => extracting sha256:7047deb9704134ff71c99791be3f6474bb45bc3971dde9257ef9186d7cb156db                                         0.0s
 => [internal] load build context                                                                                                 0.3s
 => => transferring context: 2.11kB                                                                                               0.0s
 => [dev 2/5] RUN apk add --no-cache git ca-certificates                                                                          3.8s
 => [dev 3/5] RUN adduser -D appuser                                                                                              1.7s
 => [dev 4/5] WORKDIR /src                                                                                                        0.5s
 => [dev 5/5] COPY . /src/                                                                                                        0.4s
 => [build 1/1] RUN CGO_ENABLED=0 go build -o app .                                                                              11.6s
 => [artifact 1/1] COPY --from=build /src/app /app                                                                                0.5s
 => exporting to client                                                                                                           0.1s
 => => copying files 10.00MB                                                                                                      0.1s

Una vez completada la construcción, app binario fue exportado:

$ ls
Dockerfile  app  go.mod  main.go

$ ./app
Ready to receive requests on port 8080

Docker tiene otras opciones para --output bandera documentada en su repositorio BuildKit ascendente: https://github.com/moby/buildkit#output

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

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

Cree una ruta donde desee copiar el archivo y luego usar:

docker run -d -v hostpath:dockerimag

Puede usar bind en lugar de volume si desea montar solo una carpeta, no crear un almacenamiento especial para un contenedor:

  1. construir su imagen con la etiqueta:

    docker build . -t <image>

  2. Ejecute su imagen y vincule el directorio actual de $ (pwd) donde la aplicación se almacena y mape en / raíz / ejemplo / dentro de su contenedor.

    docker run --mount type=bind,source="$(pwd)",target=/root/example/ <image> python app.py

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top