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?
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
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
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
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
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
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.
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. :)
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
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.
docker run -dit --rm IMAGE
docker cp CONTAINER:SRC_PATH DEST_PATH
https://docs.docker.com/engine/reference/commandline/run / https://docs.docker.com/engine/reference/commandline/cp /
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.
créez un chemin d'accès où vous voulez copier le fichier, puis utilisez:
docker run -d -v hostpath:dockerimag
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