¿Cuál es la forma correcta de agregar datos a un volumen con nombre existente en Docker?

88

Estaba usando Docker de la manera anterior, con un contenedor de volumen:

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

Pero ahora cambié a la nueva forma creando un volumen con nombre:

 docker volume create --name my-jenkins-volume 

Adjunté este nuevo volumen a un nuevo contenedor Jenkins. Lo único que me queda es una carpeta en la que tengo el /var/jenkins_homecontenedor jenkins anterior. (usando docker cp) Ahora quiero llenar mi nuevo volumen nombrado con el contenido de esa carpeta.

¿Puedo copiar el contenido de esa carpeta /var/lib/jenkins/volume/my-jenkins-volume/_data?

DenCowboy
fuente

Respuestas:

134

Usted puede desde luego copiar los datos directamente en /var/lib/docker/volumes/my-jenkins-volume/_data, pero al hacer esto son:

  • Depender del acceso físico al host de la ventana acoplable. Esta técnica no funcionará si está interactuando con una API de Docker remota.

  • Depender de un aspecto particular de la implementación del volumen podría cambiar en el futuro, interrumpiendo cualquier proceso que tenga que dependa de él.

Creo que es mejor confiar en las cosas que puede lograr utilizando la API de Docker, a través del cliente de línea de comandos. La solución más sencilla probablemente sea usar un contenedor auxiliar, algo como:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper
larsks
fuente
3
Con respecto a su segunda viñeta, puede ejecutar docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'para obtener su ubicación física mediante programación. Sin embargo, todavía no se siente como una gran idea.
c24w
8
Este contenedor auxiliar nunca necesita ejecutarse. Bastaría con crearlo, ejecutarlo docker cpy eliminarlo.
Alex
No puede ejecutar en ese contenedor para ver los resultados o modificar los archivos manualmente.
CodeOrElse
3
Tenga en cuenta que la lista /var/lib/docker/volumes/my-jenkins-volume/_dataal usar Docker para Mac no funciona porque los archivos se almacenan dentro de la máquina virtual xhyve . Ver forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni
1
Verdadero se explica aquí stackoverflow.com/questions/29762231/…
Zuabi
32

Puede reducir la respuesta aceptada a una línea usando, por ejemplo

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data
headdab
fuente
1
Me pregunto si la naturaleza transitoria de / tmp puede suponer un riesgo de que el contenedor elimine sus datos antes de que cp se complete. pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
jueves
1
El enlace realmente no aclara la vida útil de los archivos en / tmp. Dice: "Los programas no deben asumir que ningún archivo o directorio en / tmp se conserva entre invocaciones del programa". lo que implica que los archivos sobrevivirían, pero eso es una garantía. La opción -v para la ventana acoplable creará un directorio en el contenedor si no existe, por lo que cambiar / tmp / src por / src funcionará si le preocupa esta posible condición de carrera. Editaré la respuesta para reflejar esto, ya que no hay inconvenientes.
headdab
3
¿No -v `pwd`:/srcimplica eso que el comando se está ejecutando en el host? (¿Cómo puede el host mapear pwdsi es una máquina diferente, por ejemplo? - no puede). Si el comando docker no se está ejecutando en el host, esto no funciona. Creo que es por eso que tenemos docker cp. Esto parece que no es "el camino" para la ventana acoplable; es solo un caso especial que funciona solo cuando el comando de la ventana acoplable se ejecuta en el host. ¿Entiendo correctamente?
Wyck
Sí, creo que tienes razón. pwddebe resolverse en un archivo en la máquina host. De la documentación de montaje de la ventana acoplable: "En el caso de los montajes vinculantes, el primer campo es la ruta al archivo o directorio en la máquina host".
headdab
1
Por lo tanto, esto no funciona para copiar sus archivos locales en el contenedor si está en un host remoto, ya que está montando pwdlo que ni siquiera necesita existir en el host remoto. En cambio, la solución de Dmytro Melnychuk (create + cp + rm) copia los locales en el contenedor sin importar dónde se esté ejecutando.
Xavi Montero
25

No necesita iniciar algún contenedor para agregar datos a un volumen con nombre ya existente, simplemente cree un contenedor y copie los datos allí:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp
Dmytro Melnychuk
fuente
2
Siempre que el contenido de busybox no sea realmente necesario; puedes hacer esto con hello-worldy también funciona. busyboxes de 1,22 MB. En cambio, hello-worldes 13,3kB. La pregunta es: de la misma manera que podemos hacer un Dockerfile DESDE cero, ¿podríamos hacer una "creación de contenedor docker" con "nada" como imagen, ya que solo queremos "montar" el volumen y nunca iniciar el contenedor?
Xavi Montero
1
+1 para esta solución en la parte superior votada, pero la sintaxis correcta docker cpesdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal
3

Estos son los pasos para copiar el contenido de ~ / data al volumen de la ventana acoplable llamado my-vol

Paso 1. Adjunte el volumen a un contenedor "temporal". Para eso, ejecute en la terminal este comando:

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

Paso 2. Copie el contenido de ~ / data en my-vol . Para eso, ejecute estos comandos en una nueva ventana de terminal:

cd ~/data docker cp . alpine:/data

Esto copiará el contenido de ~ / data en my-vol volume. Después de copiar, salga del contenedor temporal.

Namik Hajiyev
fuente