Was ist der richtige Weg, um Daten zu einem vorhandenen benannten Volume in Docker hinzuzufügen?


88

Ich habe Docker auf die alte Art und Weise mit einem Volumencontainer verwendet:

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

Aber jetzt habe ich auf die neue Art gewechselt, indem ich ein benanntes Volume erstellt habe:

 docker volume create --name my-jenkins-volume 

Ich habe diesen neuen Band an einen neuen Jenkins-Container gebunden. Das einzige, was ich noch habe, ist ein Ordner, in dem ich den /var/jenkins_homemeines vorherigen Jenkins-Containers habe. (mit docker cp) Nun möchte ich mein neues benanntes Volume mit dem Inhalt dieses Ordners füllen.

Kann ich den Inhalt dieses Ordners einfach kopieren /var/lib/jenkins/volume/my-jenkins-volume/_data?

Antworten:


133

Sie können zwar Daten direkt in kopieren /var/lib/docker/volumes/my-jenkins-volume/_data, aber auf diese Weise sind Sie:

  • Verlassen Sie sich auf den physischen Zugriff auf den Docker-Host. Diese Technik funktioniert nicht, wenn Sie mit einer Remote-Docker-API interagieren.

  • Wenn Sie sich auf einen bestimmten Aspekt der Volumenimplementierung verlassen, kann sich dies in Zukunft ändern und alle Prozesse unterbrechen, die darauf angewiesen sind.

Ich denke, Sie sollten sich besser auf Dinge verlassen, die Sie mit der Docker-API über den Befehlszeilen-Client erreichen können. Die einfachste Lösung besteht wahrscheinlich darin, nur einen Hilfsbehälter zu verwenden, etwa:

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

3
In Bezug auf Ihre zweite Kugel können Sie docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'programmgesteuert den physischen Standort ermitteln. Fühlt sich immer noch nicht nach einer großartigen Idee an.
c24w

8
Dieser Helfer-Container muss niemals ausgeführt werden. Es würde ausreichen, es einfach zu erstellen, dann auszuführen docker cpund dann zu entfernen.
Alex

Sie können diesen Container nicht ausführen, um die Ergebnisse anzuzeigen oder die Dateien manuell zu ändern.
CodeOrElse

3
Beachten Sie, dass die Auflistung /var/lib/docker/volumes/my-jenkins-volume/_databei Verwendung von Docker für Mac nicht funktioniert, da Dateien in der virtuellen xhyve-Maschine gespeichert sind . Siehe forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni


32

Sie können die akzeptierte Antwort auf eine Zeile reduzieren, indem Sie z

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

1
Ich frage mich, ob die vorübergehende Natur von / tmp das Risiko birgt, dass der Container möglicherweise Ihre Daten löscht, bevor cp abgeschlossen ist. pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
verletzt

1
Der Link verdeutlicht nicht wirklich die Lebensdauer der Dateien in / tmp. Ich stelle fest: "Programme dürfen nicht davon ausgehen, dass Dateien oder Verzeichnisse in / tmp zwischen den Programmaufrufen erhalten bleiben." was bedeutet, dass die Dateien überleben würden, aber das ist eine Garantie. Die Option -v für Docker erstellt ein Verzeichnis im Container, falls es nicht vorhanden ist. Wenn Sie sich also Sorgen über diese potenzielle Race-Bedingung machen, funktioniert das Ändern von / tmp / src in / src. Ich werde die Antwort bearbeiten, um dies widerzuspiegeln, da es keinen Nachteil gibt.
Headdab

3
Bedeutet das nicht -v `pwd`:/src, dass der Befehl auf dem Host ausgeführt wird? (Wie kann der Host beispielsweise zugeordnet werden, pwdwenn es sich um einen anderen Computer handelt? - Dies ist nicht möglich.) Wenn der Docker-Befehl nicht auf dem Host ausgeführt wird, funktioniert dies nicht. Ich glaube, deshalb haben wir Docker CP. Dies scheint nicht der richtige Weg für Docker zu sein - es ist nur ein Sonderfall, der nur funktioniert, wenn der Docker-Befehl auf dem Host ausgeführt wird. Verstehe ich richtig?
Wyck

Ja, ich denke du hast recht. pwdmuss in eine Datei auf dem Host-Computer aufgelöst werden. Aus der Docker-Mount-Dokumentation: "Bei Bindungs-Mounts ist das erste Feld der Pfad zur Datei oder zum Verzeichnis auf dem Host-Computer."
Headdab

1
Daher funktioniert dies nicht, um Ihre lokalen Dateien in den Container zu kopieren, wenn Sie sich auf einem Remote-Host befinden, da Sie eine Bereitstellung durchführen, pwddie nicht einmal auf dem Remote-Host vorhanden sein muss. Stattdessen kopiert die Lösung von Dmytro Melnychuk (create + cp + rm) die lokalen in den Container, unabhängig davon, wo sie ausgeführt wird.
Xavi Montero

24

Sie müssen keinen Container starten, um Daten zu bereits vorhandenen benannten Volumes hinzuzufügen. Erstellen Sie einfach einen Container und kopieren Sie die Daten dorthin:

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

2
Vorausgesetzt, der Inhalt der Busybox wird nicht wirklich benötigt. Sie können dies mit tun hello-worldund es funktioniert auch. busyboxbeträgt 1,22 MB. Stattdessen hello-worldist 13,3kB. Die Frage ist: Genauso wie wir eine Docker-Datei von Grund auf neu erstellen können, können wir auch einen "Docker-Container erstellen" mit "nichts" als Image erstellen, da wir nur das Volume "mounten" und den Container niemals starten möchten?
Xavi Montero

1
+1 für diese Lösung docker cpdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal

2

Hier sind Schritte zum Kopieren des Inhalts von ~ / data auf das Docker-Volume mit dem Namen my-vol

Schritt 1. Befestigen Sie das Volume an einem "temporären" Container. Führen Sie dazu im Terminal diesen Befehl aus:

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

Schritt 2. Kopieren Sie den Inhalt von ~ / data in my-vol . Führen Sie dazu diese Befehle im neuen Terminalfenster aus:

cd ~/data docker cp . alpine:/data

Dadurch wird der Inhalt von ~ / data in mein vol- Volume kopiert . Nach dem Kopieren verlassen Sie den temporären Container.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.