148 votes

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

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é de méthode en créant un volume nommé :

 docker volume create --name my-jenkins-volume 

J'ai relié ce nouveau volume à un nouveau conteneur Jenkins. La seule chose qu'il me reste est un dossier dans lequel j'ai le fichier /var/jenkins_home de 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 vers /var/lib/jenkins/volume/my-jenkins-volume/_data ?

211voto

larsks Points 23184

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

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

  • Le fait de dépendre d'un aspect particulier de l'implémentation du volume pourrait changer à l'avenir, brisant tous les processus que vous avez qui en dépendent.

Je pense qu'il est préférable de s'appuyer sur des choses que vous pouvez accomplir en utilisant l'api docker, via le client de ligne de commande. La solution la plus simple est probablement 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

3 votes

En ce qui concerne votre deuxième point, vous pouvez exécuter docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}' pour obtenir son emplacement physique de manière programmatique. Mais ce n'est toujours pas une bonne idée.

16 votes

Ce conteneur d'aide n'a jamais besoin de s'exécuter réellement. Il suffirait de le créer, puis de lancer la commande docker cp puis le retirer.

0 votes

Vous ne pouvez pas exécuter dans ce conteneur pour voir les résultats ou modifier les fichiers manuellement.

65voto

Dmytro Melnychuk Points 609

Vous n'avez pas besoin de démarrer un conteneur pour ajouter des données à un volume nommé existant, il suffit de créer un conteneur et d'y copier les données :

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp

46voto

headdab Points 449

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

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data

1 votes

Je me demande si la nature transitoire de /tmp ne pose pas un risque de suppression de vos données par le conteneur avant la fin du cp ? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES

1 votes

Le lien ne précise pas vraiment la durée de vie des fichiers dans /tmp. Il indique : "Les programmes ne doivent pas supposer que les fichiers ou répertoires dans /tmp sont préservés entre les invocations du programme", ce qui implique que les fichiers survivraient, mais ce n'est pas une garantie. L'option -v de docker créera un répertoire dans le conteneur s'il n'existe pas, donc changer /tmp/src en /src fonctionnera si vous êtes inquiet de cette condition de course potentielle. Je vais modifier la réponse pour refléter cela, car il n'y a pas d'inconvénient.

4 votes

N'est pas le -v `pwd`:/src implique que la commande s'exécute sur l'hôte ? (Comment l'hôte peut-il mettre en correspondance pwd s'il s'agit d'une machine différente, par exemple ? -- ce n'est pas possible). Si la commande docker n'est pas exécutée sur l'hôte, cela ne fonctionne pas. Je crois que c'est la raison pour laquelle nous avons docker cp. Cela semble ne pas être "la voie" pour docker -- c'est juste un cas spécial qui ne fonctionne que lorsque la commande docker est exécutée sur l'hôte. Est-ce que je comprends bien ?

9voto

maiermic Points 1620

Vous pouvez ajouter cette fonction BASH à votre .bashrc pour copier des fichiers sur un volume Docker existant sans exécuter un conteneur

# Usage: copy-to-docker-volume SRC_PATH DEST_VOLUME_NAME [DEST_PATH]
copy-to-docker-volume() {
  SRC_PATH=$1
  DEST_VOLUME_NAME=$2
  DEST_PATH="${3:-}"
  # create smallest Docker image possible
  echo -e 'FROM scratch\nLABEL empty=""' | docker build -t empty -
  # create temporary container to be able to mount volume
  CONTAINER_ID=$(docker container create -v my-volume:/data empty cmd)
  # copy files to volume
  docker cp "${SRC_PATH}" "${CONTAINER_ID}":"/data/${DEST_PATH}"
  # remove temporary container
  docker rm "${CONTAINER_ID}"
}

Exemple

# create volume as destination
docker volume create my-volume
# create directory to copy
mkdir my-dir
echo "hello file1" > my-dir/my-file-1
# copy directory to volume
copy-to-docker-volume my-dir my-volume
# list directory on volume
docker run --rm -it -v my-volume:/data busybox ls -la /data/my-dir
# show file content on volume
docker run --rm -it -v my-volume:/data busybox cat /data/my-dir/my-file-1

# create another fil to copy
echo "hello file2" > my-file-2
# copy file to directory on volume
copy-to-docker-volume my-file-2 my-volume my-dir
# list (updated) directory on volume
docker run --rm -it -v my-volume:/data busybox ls -la /data/my-dir
# check volume content
docker run --rm -it -v my-volume:/data busybox cat /data/my-dir/my-file-2

8voto

Namik Hajiyev Points 11

Voici les étapes à suivre pour copier le contenu de ~/data vers le volume docker nommé mon-volume

Étape 1. Attachez le volume à un conteneur "temporaire". Pour cela exécutez dans le terminal cette commande :

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

Étape 2. Copiez le contenu de ~/data sur mon-volume . Pour cela, exécutez cette commande dans une nouvelle fenêtre de terminal :

cd ~/data docker cp . alpine:/data

Ceci copiera le contenu de ~/data sur mon-volume volume. Après la copie, quittez le conteneur temporaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X