Ma question concerne cette question sur la copie de fichiers de conteneurs à des hôtes; J'ai un fichier Docker qui récupère les dépendances, compile un artefact de construction à partir de la source et exécute un exécutable. Je souhaite également copier l'artefact de construction (dans mon cas, il s'agit d'un .Zip
produit par sbt dist
dans '../ target/`, mais je pense que cette question s'applique également aux fichiers jar, binaires, etc.
docker cp
fonctionne sur des conteneurs, pas des images; Ai-je besoin de démarrer un conteneur simplement pour en extraire un fichier? Dans un script, j'ai essayé d'exécuter /bin/bash
en mode interactif en arrière-plan, de copier le fichier, puis de tuer le conteneur, mais cela semble correct. Y a-t-il un meilleur moyen?
D'autre part, je voudrais éviter de décompresser un fichier .tar
après avoir exécuté docker save $IMAGENAME
uniquement pour extraire un fichier (mais cela semble être l'option la plus simple, si elle est la plus lente, actuellement).
J'utiliserais des volumes de docker, par exemple:
docker run -v hostdir:out $IMAGENAME /bin/cp/../blah.Zip /out
mais j’exécute boot2docker
sous OSX et je ne sais pas comment écrire directement sur mon système de fichiers hôte Mac (des volumes en lecture-écriture montent dans ma machine virtuelle boot2docker, ce qui signifie que je ne peux pas partager facilement un script pour extraire blah.Zip
image avec les autres.
Répondre à une vieille question pour des références. Pour copier un fichier à partir d'une image, créez un conteneur temporaire, copiez-le puis supprimez-le:
id=$(docker create image-name)
docker cp $id:path - > local-tar-file
docker rm -v $id
Malheureusement, il ne semble pas y avoir de moyen de copier des fichiers directement à partir d'images Docker. Vous devez d'abord créer un conteneur, puis copier le fichier à partir du conteneur.
Cependant, si votre image contient une commande cat
(et cela se fera souvent), vous pouvez le faire avec une seule commande:
docker run --rm --entrypoint cat yourimage /path/to/file > path/to/destination
Si votre image ne contient pas cat
, créez simplement un conteneur et utilisez la commande docker cp
comme suggéré dans la réponse d'Igor.
Une option beaucoup plus rapide consiste à copier le fichier du conteneur en cours d'exécution sur un volume monté:
time docker run -v $PWD:/opt/mount --rm --entrypoint cp image:version /data/libraries.tgz /opt/mount/libraries.tgz
real 0m0.446s
CONTRE
docker run --rm --entrypoint cat image:version /data/libraries.tgz > libraries.tgz
real 0m9.014s
Le commentaire du parent a déjà montré comment utiliser cat . Vous pouvez aussi utiliser tar de la même manière:
docker run yourimage tar -c -C /my/directory subfolder | tar x
J'utilise boot2docker sur MacOS. Je peux vous assurer que les scripts basés sur "docker cp" sont portables. Parce que toute commande est relayée à l'intérieur de boot2docker mais que le flux binaire est retransmis au client en ligne de commande de docker exécuté sur votre mac. Les opérations d'écriture à partir du client docker sont donc exécutées à l'intérieur du serveur et écrites dans l'instance du client en cours d'exécution!
Je partage un script de sauvegarde des volumes de menu fixe avec tous les conteneurs de menu fixe que je fournis et mes scripts de sauvegarde sont testés sous Linux et MacOS avec boot2docker. Les sauvegardes peuvent être facilement échangées entre les plates-formes. Fondamentalement, j'exécute la commande suivante dans mon script:
docker run --name=bckp_for_volume --rm --volumes-from jenkins_jenkins_1 -v /Users/github/jenkins/backups:/backup busybox tar cf /backup/JenkinsBackup-2015-07-09-14-26-15.tar /jenkins
Exécute un nouveau conteneur busybox et monte le volume de mon conteneur jenkins avec le nom jenkins_jenkins_1. Le volume entier est écrit dans les sauvegardes de fichier/JenkinsBackup-2015-07-09-14-26-15.tar
J'ai déjà déplacé des archives entre le conteneur linux et mon conteneur mac sans aucun ajustement du script de sauvegarde ou de restauration. Si c'est ce que vous voulez, vous trouverez le script entier dans un tutoriel ici: blacklabelops/jenkins
Vous pourriez lier un chemin local de l'hôte vers un chemin du conteneur, puis cp
le (s) fichier (s) souhaité (s) vers ce chemin à la fin de votre script.
$ docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latest
Ensuite, il n'est pas nécessaire de copier après.