Quelle est la bonne façon d'ajouter des données à un volume nommé existant dans Docker?

88

J'utilisais Docker à l'ancienne, avec un conteneur de volume:

docker run -d --name jenkins-data jenkins:tag echo "data-only container for Jenkins"

Mais maintenant, j'ai changé pour la nouvelle façon en créant un volume nommé:

 docker volume create --name my-jenkins-volume 

J'ai lié ce nouveau volume à un nouveau conteneur Jenkins. La seule chose qui me reste est un dossier dans lequel j'ai le /var/jenkins_homede mon précédent conteneur jenkins. (en utilisant docker cp) Maintenant, je veux remplir mon nouveau volume nommé avec le contenu de ce dossier.

Puis-je simplement copier le contenu de ce dossier dans /var/lib/jenkins/volume/my-jenkins-volume/_data?

DenCowboy
la source

Réponses:

134

Vous pouvez certainement copier des données directement dans /var/lib/docker/volumes/my-jenkins-volume/_data, mais en faisant cela, vous êtes:

  • S'appuyant sur l'accès physique à l'hôte docker. Cette technique ne fonctionnera pas si vous interagissez avec une API Docker distante.

  • S'appuyer sur un aspect particulier de l'implémentation du volume pourrait changer à l'avenir, interrompant tous les processus dont vous disposez qui en dépendent.

Je pense que vous feriez mieux de vous fier aux choses que vous pouvez accomplir en utilisant l'api docker, via le client de ligne de commande. La solution la plus simple est probablement simplement d'utiliser un conteneur d'aide, quelque chose comme:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper
larsks
la source
3
En ce qui concerne votre deuxième puce, vous pouvez exécuter docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'pour obtenir son emplacement physique par programme. Cela ne me semble toujours pas une bonne idée.
c24w
8
Ce conteneur d'assistance n'a jamais besoin de s'exécuter. Il suffirait simplement de le créer, puis de l'exécuter docker cppuis de le supprimer.
Alex
Vous ne pouvez pas exécuter dans ce conteneur pour voir les résultats ou modifier les fichiers manuellement.
CodeOrElse
3
Notez que la liste /var/lib/docker/volumes/my-jenkins-volume/_datalors de l'utilisation de Docker pour Mac ne fonctionne pas car les fichiers sont stockés dans la machine virtuelle xhyve . Voir forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni
1
Le vrai est expliqué ici stackoverflow.com/questions/29762231/…
Zuabi
32

Vous pouvez réduire la réponse acceptée à une ligne en utilisant, par exemple

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data
headdab
la source
1
Je me demande si la nature transitoire de / tmp peut poser un risque que le conteneur supprime éventuellement vos données avant la fin de cp? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
thurt
1
Le lien ne clarifie pas vraiment la durée de vie des fichiers dans / tmp. Je déclare: "Les programmes ne doivent pas supposer que les fichiers ou répertoires dans / tmp sont préservés entre les appels du programme." ce qui implique que les fichiers survivraient, mais c'est une garantie. L'option -v pour docker créera un répertoire dans le conteneur s'il n'existe pas, donc changer / tmp / src en / src fonctionnera si vous êtes préoccupé par cette condition de concurrence potentielle. Je vais modifier la réponse pour refléter cela, car il n'y a pas d'inconvénient.
headdab
3
cela -v `pwd`:/srcn'implique- t-il pas que la commande s'exécute sur l'hôte? (Comment l'hôte peut-il mapper pwds'il s'agit d'une machine différente, par exemple? - il ne peut pas.) Si la commande docker ne s'exécute pas sur l'hôte, cela ne fonctionne pas. Je crois que c'est pourquoi nous avons docker cp. Il semble que ce n'est pas "la voie" pour docker - c'est juste un cas spécial qui ne fonctionne que lorsque la commande docker est en cours d'exécution sur l'hôte. Est-ce que je comprends bien?
Wyck
Oui, je pense que vous avez raison. pwddoit être résolu en un fichier sur la machine hôte. De la documentation de montage de docker: "Dans le cas des montages de liaison, le premier champ est le chemin d'accès au fichier ou au répertoire sur la machine hôte."
headdab
1
Par conséquent, cela ne fonctionne pas pour copier vos fichiers locaux dans le conteneur s'ils se trouvent dans un hôte distant, car vous montez pwdce qui n'a même pas besoin d'exister dans l'hôte distant. Au lieu de cela, la solution de Dmytro Melnychuk (create + cp + rm) copie les locales dans le conteneur, peu importe où elle s'exécute.
Xavi Montero
25

Vous n'avez pas besoin de démarrer un conteneur pour ajouter des données à un volume nommé déjà existant, créez simplement un conteneur et copiez-y les données:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp
Dmytro Melnychuk
la source
2
A condition que le contenu de busybox ne soit pas vraiment nécessaire; vous pouvez le faire avec hello-worldet cela fonctionne également. busyboxest de 1,22 Mo. Au lieu de cela, hello-world13,3 Ko. La question est la suivante: de la même manière que nous pouvons faire un Dockerfile FROM scratch, pourrions-nous faire un "docker container create" avec "rien" comme image car nous voulons simplement "monter" le volume et ne jamais démarrer le conteneur?
Xavi Montero
1
+1 pour cette solution sur le dessus a voté mais la syntaxe correcte pour docker cpestdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal
3

Voici les étapes pour copier le contenu de ~ / data vers le volume docker nommé my-vol

Étape 1. Fixez le volume à un conteneur «temporaire». Pour cela, exécutez cette commande dans le terminal:

docker run --rm -it --name alpine --mount type=volume,source=my-vol,target=/data alpine

Étape 2. Copiez le contenu de ~ / data dans my-vol . Pour cela, exécutez ces commandes dans une nouvelle fenêtre de terminal:

cd ~/data docker cp . alpine:/data

Cela copiera le contenu de ~ / data dans le volume my-vol . Après la copie, quittez le conteneur temporaire.

Namik Hajiyev
la source