Question Copie de fichiers du conteneur Docker vers l'hôte


Je pense à utiliser Docker pour créer mes dépendances sur un serveur d'intégration continue (CI), de sorte que je n'ai pas besoin d'installer tous les runtimes et bibliothèques sur les agents eux-mêmes. Pour ce faire, j'ai besoin de copier les artefacts de construction qui sont construits à l'intérieur du conteneur dans l'hôte.

Est-ce possible?


833
2018-02-26 17:46


origine


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 reçu 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

1557
2018-02-26 18:31



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 n'est plus en cours d'exécution, il a déjà copié les artefacts de la construction dans le artifacts répertoire sur l'hôte.

MODIFIER:

CAVEAT: lorsque vous faites cela, vous pouvez rencontrer des problèmes avec l'ID utilisateur de l'utilisateur docker correspondant à l'ID utilisateur de l'utilisateur en cours d'exécution. Autrement dit, les fichiers dans /artifacts s'affichera comme appartenant à l'utilisateur avec l'UID de l'utilisateur utilisé dans le conteneur docker. Un moyen de contourner 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

53
2017-10-01 20:58



Monter un volume, copier les artefacts, ajuster l'identifiant du propriétaire et l'identifiant du 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

16
2018-03-30 15:28



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 d'hôte, chown l'artefact, cp l'artefact au volume hôte:

$ 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 prises $(id -u):$(id -g) les valeurs provenant de l'extérieur du conteneur en cours d'exécution; c'est-à-dire, l'hôte docker.

Les avantages sur docker cp sont:

  • vous n'êtes pas obligé de docker run --name votre récipient avant
  • vous n'êtes pas obligé de docker container rm après

11
2018-05-07 15:54



Je poste ceci pour n'importe qui qui emploie 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 cette backup le répertoire est créé automatiquement.

J'espère que cela sera utile à quelqu'un un jour. :)


6
2018-01-17 08:10



Si vous n'avez pas de conteneur en cours d'exécution, juste une image, et en supposant que vous voulez copier seulement 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

6
2017-11-09 23:06



En tant que 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 Docker à créer et à utiliser.

Il va monter l'espace de travail dans le conteneur en tant que volume (avec l'utilisateur approprié), le définir 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 le code sur l'interface utilisateur) pour ce faire, avec la commande image.inside () {}.

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


3
2017-09-13 04:39



La plupart des réponses n'indiquent pas que le conteneur doit être exécuté avant docker cp marchera:

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

3
2018-04-05 05:40