Copier des fichiers du conteneur Docker vers l'hôte

je pense utiliser Docker pour construire mes dépendances sur un serveur d'intégration continue (CI), de sorte que je n'ai pas à installer toutes les durées d'exécution et les bibliothèques sur les agents eux-mêmes. Pour réaliser cela, j'aurais besoin de copier l'accumulation des objets qui sont construits à l'intérieur du contenant dans l'hôte.

est-ce possible?

903
demandé sur lospejos 2014-02-26 21:46:52

13 réponses

pour copier un fichier d'un conteneur vers l'hôte, vous pouvez utiliser la commande

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

voici un exemple:

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

ici goofy_roentgen est le nom que j'ai obtenu de la commande suivante:

[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
répondu creack 2017-11-12 19:10:28

montez un "volume" et copiez-y les artefacts:

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

ensuite, lorsque la construction se termine et que le conteneur ne tourne plus, il a déjà copié les artefacts de la construction dans le répertoire artifacts sur l'hôte.

EDIT:

avertissement: lorsque vous faites cela, vous pouvez rencontrer des problèmes avec l'ID utilisateur du docker correspondant à l'id utilisateur de l'utilisateur courant. Qui est, les fichiers de /artifacts sera affiché comme possédés par l'utilisateur avec l'UID de l'utilisateur utilisé à l'intérieur du conteneur docker. Un moyen d'éviter cela peut être d'utiliser L'UID de l'utilisateur appelant:

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
répondu djhaskin987 2014-10-23 16:08:49

montez un volume, copiez les artefacts, ajustez le numéro d'identification du propriétaire et le numéro de groupe:

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
répondu Dimchansky 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

plus long...

docker run avec un volume hôte, chown l'artefact, cp l'artefact à l'hôte de volume:

$ 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

cette astuce fonctionne parce que le chown invocation dans le heredoc les prend $(id -u):$(id -g) valeurs de l'extérieur du conteneur courant; c.-à-d., l'hôte docker.

les prestations docker cp sont:

  • vous n'avez pas à docker run --name votre récipient avant de
  • vous n'avez pas à docker container rm après
12
répondu rubicks 2017-06-12 17:34:15

si vous n'avez pas de conteneur en cours d'exécution, juste une image, et en supposant que vous voulez copier juste un fichier texte, vous pouvez faire quelque chose comme ceci:

docker run the-image cat path/to/container/file.txt > path/to/host/file.txt
10
répondu cancerbero 2018-07-23 10:59:09

vous ne devez pas utiliser docker run

vous pouvez le faire avec docker create

du docs la commande docker create crée une couche de conteneur inscriptible au-dessus de l'image spécifiée et la prépare pour l'exécution de la commande spécifiée. L'ID du conteneur est ensuite imprimé sur STDOUT. Ceci est similaire à docker run-d sauf que le conteneur n'est jamais démarré.

donc, vous pouvez faire

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

ici, on ne démarre jamais le container. Qui a regardé bénéfiques pour moi.

8
répondu Ishan Bhatt 2018-07-05 08:25:27

je poste ceci pour quiconque utilise Docker pour Mac. C'est ce qui a fonctionné pour moi:

 $ mkdir mybackup # local directory on Mac

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

notez que lorsque je monte en utilisant -v ce répertoire backup est automatiquement créé.

j'espère que ce sera utile à quelqu'un un jour. :)

6
répondu Paul 2017-01-17 08:10:44

la plupart des réponses n'indiquent pas que le conteneur doit courir avant docker cp fonctionnera:

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
répondu cmcginty 2018-07-23 10:59:46

comme solution plus générale, il y a un plugin CloudBees pour Jenkins à construire à l'intérieur d'un conteneur Docker . Vous pouvez sélectionner une image à utiliser à partir d'un registre Docker ou définir un fichier Dockerfile à construire et à utiliser.

il montera l'espace de travail dans le conteneur comme un volume (avec l'utilisateur approprié), le définira comme votre répertoire de travail, faire toutes les commandes que vous demandez (à l'intérieur du conteneur). Vous pouvez également utiliser le plugin docker-workflow (si vous préférez code de l'INTERFACE utilisateur) pour ce faire, avec l'image.à l'intérieur() {} de commande.

essentiellement tout cela, cuit dans votre serveur de CI/CD et puis certains.

3
répondu BobMcGee 2015-11-19 19:03:34
2
répondu shuaihanhungry 2018-05-16 02:55:20

si vous voulez simplement extraire un fichier d'une image (au lieu d'un conteneur en cours d'exécution) vous pouvez faire ceci:

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

Cela permet d'ouvrir le conteneur, écrire le nouveau fichier, puis retirez le récipient. Un inconvénient, cependant, est que les permissions de fichier et la date modifiée ne sera pas préservée.

1
répondu s g 2017-12-30 04:06:37

créez un chemin d'accès où vous voulez copier le fichier, puis utilisez:

docker run -d -v hostpath:dockerimag
0
répondu Chandra Pal 2018-07-23 11:00:11

Créer un répertoire de données sur le système hôte (à l'extérieur du récipient) et le monter dans un répertoire visible de l'intérieur du conteneur. Cela place les fichiers dans un emplacement connu sur le système hôte, et il est facile pour les outils et les applications sur le système hôte pour accéder aux fichiers

docker run -d -v /path/to/Local_host_dir:/path/to/docker_dir docker_image:tag
-1
répondu Innocent Anigbo 2017-05-20 10:36:34