Qual è il modo giusto per aggiungere dati a un volume denominato esistente in Docker?


91

Stavo usando Docker alla vecchia maniera, con un contenitore di volumi:

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

Ma ora sono passato al nuovo modo creando un volume con nome:

 docker volume create --name my-jenkins-volume 

Ho associato questo nuovo volume a un nuovo contenitore Jenkins. L'unica cosa che mi è rimasta è una cartella in cui ho il /var/jenkins_homecontenitore del mio precedente jenkins. (utilizzando docker cp) Ora voglio riempire il mio nuovo volume con nome con il contenuto di quella cartella.

Posso semplicemente copiare il contenuto di quella cartella in /var/lib/jenkins/volume/my-jenkins-volume/_data?

Risposte:


141

È possibile certamente copiare i dati direttamente in /var/lib/docker/volumes/my-jenkins-volume/_data, ma in questo modo si è:

  • Affidarsi all'accesso fisico al docker host. Questa tecnica non funzionerà se stai interagendo con un'API Docker remota.

  • Affidarsi a un aspetto particolare dell'implementazione del volume potrebbe cambiare in futuro, interrompendo tutti i processi che si basano su di esso.

Penso che sia meglio fare affidamento su cose che puoi realizzare usando l'API Docker, tramite il client della riga di comando. La soluzione più semplice è probabilmente usare solo un contenitore di supporto, qualcosa come:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper

3
Per quanto riguarda il tuo secondo proiettile, puoi correre docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'per ottenere la sua posizione fisica a livello di programmazione. Tuttavia, non sembra ancora una grande idea.
c24w

9
Questo contenitore di supporto non deve mai essere eseguito effettivamente. Basterebbe semplicemente crearlo, quindi eseguirlo docker cpe quindi rimuoverlo.
Alex

Non puoi eseguire in quel contenitore per vedere i risultati o modificare i file manualmente.
CodeOrElse

3
Tieni presente che l'elenco /var/lib/docker/volumes/my-jenkins-volume/_dataquando si utilizza Docker per Mac non funziona perché i file sono archiviati nella macchina virtuale xhyve . Vedi forum.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni


32

È possibile ridurre la risposta accettata a una riga utilizzando, ad es

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

1
Mi chiedo se la natura transitoria di / tmp possa comportare il rischio che il contenitore possa cancellare i tuoi dati prima del completamento di cp? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
thurt

1
Il collegamento non chiarisce realmente la durata dei file in / tmp. Dichiaro: "I programmi non devono presumere che alcun file o directory in / tmp venga preservato tra le invocazioni del programma." il che implica che i file sopravviveranno, ma questa è una garanzia. L'opzione -v per docker creerà una directory nel contenitore se non esiste, quindi cambiare / tmp / src in / src funzionerà se sei preoccupato per questa potenziale condizione di competizione. Modificherò la risposta per riflettere questo, poiché non ci sono svantaggi.
headdab

3
non -v `pwd`:/srcimplica che il comando sia in esecuzione sull'host? (Come può l'host mappare pwdse è una macchina diversa, per esempio? - non può.) Se il comando docker non è in esecuzione sull'host, non funziona. Credo che sia per questo che abbiamo docker cp. Sembra che non sia "la strada" per docker: è solo un caso speciale che funziona solo quando il comando docker è in esecuzione sull'host. Ho capito bene?
Wyck

Sì, penso che tu abbia ragione. pwddeve risolversi in un file sulla macchina host. Dalla documentazione di montaggio di Docker: "Nel caso di montaggi bind, il primo campo è il percorso del file o della directory sul computer host."
headdab

1
Pertanto, questo non funziona per copiare i vostri file locali nel contenitore se in un host remoto, come si sta montando pwdche non ha nemmeno bisogno di esistere nel host remoto. Invece la soluzione di Dmytro Melnychuk (create + cp + rm) copia quelli locali nel contenitore, indipendentemente da dove sia in esecuzione.
Xavi Montero

27

Non è necessario avviare un contenitore per aggiungere dati a un volume denominato già esistente, basta creare un contenitore e copiare i dati lì:

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

2
A condizione che i contenuti di busybox non siano realmente necessari; puoi farlo con hello-worlde funziona anche. busyboxè 1,22 MB. Invece hello-worldè 13,3kB. La domanda è: nello stesso modo in cui possiamo fare un Dockerfile DA zero, potremmo fare un "docker container create" con "niente" come immagine poiché vogliamo solo "montare" il volume e non avviare mai il contenitore?
Xavi Montero

1
+1 per questa soluzione votata sopra le righe ma la sintassi corretta per docker cpèdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal

4

Di seguito sono riportati i passaggi per copiare il contenuto di ~ / data nel volume docker denominato my-vol

Passaggio 1. Collegare il volume a un contenitore "temporaneo". Per quella esecuzione nel terminale questo comando:

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

Passaggio 2. Copia il contenuto di ~ / data in my-vol . Per questo, esegui questi comandi nella nuova finestra del terminale:

cd ~/data docker cp . alpine:/data

Questo copierà il contenuto di ~ / data nel volume my-vol . Dopo la copia, esci dal contenitore temporaneo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.