Je songe à utiliser Docker pour créer mes dépendances sur un serveur d'intégration continue (CI), de sorte que je n'ai pas à installer toutes les bibliothèques d'exécution et les bibliothèques sur les agents eux-mêmes.
Pour ce faire, je devrais copier les artefacts de construction construits à l'intérieur du conteneur dans l'hôte. Est-ce possible?
Pour copier un fichier d’un conteneur sur l’hôte, vous pouvez utiliser la commande
docker cp <containerId>:/file/path/within/container /Host/path/target
Voici un exemple:
$ Sudo docker cp goofy_roentgen:/out_read.jpg .
Ici goofy_roentgen est le nom que j'ai obtenu avec la commande suivante:
$ 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
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 est terminée et que le conteneur n'est plus en cours d'exécution, il a déjà copié les artefacts de la construction dans le répertoire artifacts
de l'hôte.
Caveat: Dans ce cas, 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. C'est-à-dire que les fichiers de /artifacts
seront affichés comme appartenant à l'utilisateur avec l'UID de l'utilisateur utilisé dans le conteneur de menu fixe. Une solution consiste à 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
Vous n'avez pas besoin d'utiliser docker run
Vous pouvez le faire avec docker create
A partir de la documentation La commande docker create crée un calque de conteneur inscriptible sur l'image spécifiée et la prépare pour l'exécution de la commande spécifiée. L'ID de conteneur est ensuite imprimé sur STDOUT. Cette opération est similaire à docker run -d, sauf que le conteneur est jamais commencé.
Alors tu peux faire
docker create -ti --name dummy IMAGE_NAME bash
docker cp dummy:/path/to/file /dest/to/file
docker rm -fv dummy
Ici, vous ne démarrez jamais le conteneur. Cela m'a semblé bénéfique.
Montez un volume, copiez les artefacts, ajustez 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
$ 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
docker run
avec un volume hôte, chown
l'artefact, cp
l'artefact du 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 car l'invocation chown
au sein des valeurs heredoc the prend $(id -u):$(id -g)
de l'extérieur du conteneur en cours d'exécution; c'est-à-dire l'hôte de docker.
Les avantages sont:
docker container run --name
ou docker container create --name
avantdocker container rm
aprèsSi vous n'avez pas de conteneur en cours d'exécution, juste une image, et en supposant que vous vouliez copier uniquement un fichier texte, vous pourriez faire quelque chose comme ceci:
docker run the-image cat path/to/container/file.txt > path/to/Host/file.txt
La plupart des réponses n'indiquent pas que le conteneur doit être exécuté avant que docker cp
fonctionne:
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
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 cela sera utile à quelqu'un un jour. :)
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/
Comme solution plus générale, il existe un plugin CloudBees que Jenkins peut construire à l'intérieur d'un conteneur Docker . Vous pouvez sélectionner une image à utiliser dans un registre Docker ou définir un fichier Docker à créer et à utiliser.
Il monte l'espace de travail dans le conteneur en tant que volume (avec l'utilisateur approprié), le définit comme votre répertoire de travail et exécute les commandes que vous demandez (à l'intérieur du conteneur). Vous pouvez également utiliser le plug-in docker-workflow (si vous préférez le code sur l'interface utilisateur) pour ce faire, avec la commande image.inside () {}.
En gros, tout cela est intégré à votre serveur CI/CD, puis à d’autres.
Si vous voulez simplement extraire un fichier d'un image (au lieu d'un conteneur en cours d'exécution), vous pouvez faire ceci:
docker run --rm <image> cat <source> > <local_dest>
Cela fera apparaître le conteneur, écrira le nouveau fichier, puis supprimera le conteneur. Un inconvénient, cependant, est que les autorisations de fichier et la date de modification ne seront pas préservées.
J'ai utilisé PowerShell (Admin) avec cette commande.
docker cp {container id}:{container path}/error.html C:\\error.html
Exemple
docker cp ff3a6608467d:/var/www/app/error.html C:\\error.html
Vous pouvez utiliser bind
au lieu de volume
si vous voulez monter un seul dossier, sans créer de stockage spécial pour un conteneur:
Construisez votre image avec la balise:
docker build . -t <image>
Exécutez votre image et liez le répertoire $ (pwd) actuel où app.py est stocké et mappez-le sur/root/example/à l'intérieur de votre conteneur.
docker run --mount type=bind,source="$(pwd)",target=/root/example/ <image> python app.py
Créez un chemin où vous voulez copier le fichier puis utilisez:
docker run -d -v hostpath:dockerimag