Jaki jest właściwy sposób dodawania danych do istniejącego nazwanego woluminu w Dockerze?

88

Używałem Dockera w stary sposób, z kontenerem objętości:

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

Ale teraz przeszedłem na nowy sposób, tworząc nazwany wolumin:

 docker volume create --name my-jenkins-volume 

Powiązałem ten nowy tom z nowym kontenerem Jenkinsa. Jedyne, co mi zostało, to folder, w którym mam /var/jenkins_homemój poprzedni kontener Jenkins. (używającdocker cp ) Teraz chcę wypełnić mój nowy nazwany wolumin zawartością tego folderu.

Czy mogę po prostu skopiować zawartość tego folderu do /var/lib/jenkins/volume/my-jenkins-volume/_data?

DenCowboy
źródło

Odpowiedzi:

134

Państwo może oczywiście skopiować dane bezpośrednio /var/lib/docker/volumes/my-jenkins-volume/_data, ale w ten sposób jesteś:

  • Poleganie na fizycznym dostępie do hosta platformy Docker. Ta technika nie zadziała, jeśli korzystasz ze zdalnego interfejsu API platformy Docker.

  • Poleganie na konkretnym aspekcie implementacji wolumenu może się zmienić w przyszłości, przerywając wszelkie procesy, które na nim polegają.

Myślę, że lepiej polegać na rzeczach, które można osiągnąć za pomocą interfejsu docker API, za pośrednictwem klienta wiersza poleceń. Najłatwiejszym rozwiązaniem jest prawdopodobnie użycie pomocniczego kontenera, na przykład:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper
larsks
źródło
3
Jeśli chodzi o drugą kulę, możesz docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'programowo pobierać jej fizyczną lokalizację. Jednak nadal nie wydaje się to świetnym pomysłem.
c24w
8
Ten kontener pomocniczy nigdy nie musi faktycznie działać. Wystarczyłoby po prostu go utworzyć, uruchomić, docker cpa następnie usunąć.
Alex
Nie możesz wykonać do tego kontenera, aby zobaczyć wyniki lub ręcznie zmodyfikować pliki.
CodeOrElse
3
Zwróć uwagę, że lista /var/lib/docker/volumes/my-jenkins-volume/_datapodczas korzystania z Docker for Mac nie działa, ponieważ pliki są przechowywane w maszynie wirtualnej xhyve . Zobacz forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ortomala Lokni
1
Prawda jest wyjaśniona tutaj stackoverflow.com/questions/29762231/…
Zuabi
32

Zaakceptowaną odpowiedź możesz zredukować do jednej linii używając np

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data
headdab
źródło
1
Zastanawiam się, czy przejściowy charakter / tmp może stwarzać ryzyko, że kontener prawdopodobnie usunie Twoje dane przed zakończeniem procesu cp? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
thurt
1
Odsyłacz tak naprawdę nie wyjaśnia czasu życia plików w / tmp. I stwierdza: „Programy nie mogą zakładać, że jakiekolwiek pliki lub katalogi w / tmp są zachowane pomiędzy wywołaniami programu”. co oznacza, że ​​pliki przetrwają, ale to gwarancja. Opcja -v dla docker utworzy katalog w kontenerze, jeśli nie istnieje, więc zmiana / tmp / src na / src będzie działać, jeśli martwisz się o ten potencjalny stan wyścigu. Zmienię odpowiedź, aby to odzwierciedlić, ponieważ nie ma wady.
headdab
3
czy nie -v `pwd`:/srcoznacza to, że polecenie działa na hoście? (Jak na przykład może mapować hosta, pwdjeśli jest to inny komputer? - nie może.) Jeśli polecenie docker nie jest uruchomione na hoście, to nie działa. Uważam, że właśnie dlatego mamy docker cp. Wygląda na to, że nie jest to „droga” dla dockera - to tylko specjalny przypadek, który działa tylko wtedy, gdy polecenie docker jest uruchomione na hoście. Czy dobrze rozumiem?
Wyck
Tak, myślę, że masz rację. pwdmusi rozwiązać się do pliku na komputerze hosta. Z dokumentacji montowania Dockera: "W przypadku montowań bind, pierwsze pole to ścieżka do pliku lub katalogu na maszynie hosta."
headdab
1
W związku z tym, to nie działa na kopiowanie swoich plików lokalnych do pojemnika , jeśli w zdalnym hostem, jak montujesz pwdktóry nawet nie musi istnieć w zdalnym hostem. Zamiast tego rozwiązanie autorstwa Dmytro Melnychuka (create + cp + rm) kopiuje te lokalne do kontenera bez względu na to, gdzie jest uruchomione.
Xavi Montero
25

Nie musisz uruchamiać jakiegoś kontenera, aby dodać dane do już istniejącego woluminu nazwanego, po prostu utwórz kontener i skopiuj tam dane:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp
Dmytro Melnychuk
źródło
2
Pod warunkiem, że zawartość busyboxa nie jest naprawdę potrzebna; możesz to zrobić hello-worldi to też działa. busyboxwynosi 1,22 MB. Zamiast tego hello-worldjest 13,3kB. Pytanie brzmi: w ten sam sposób, w jaki możemy zrobić plik Dockerfile FROM zera, czy moglibyśmy zrobić „tworzenie kontenera dockera” z „niczym” jako obrazem, ponieważ chcemy tylko „zamontować” wolumin i nigdy nie uruchamiać kontenera?
Xavi Montero
1
+1 dla tego rozwiązania w głosowaniu, ale prawidłowa składnia docker cptodocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal
3

Oto kroki kopiowania zawartości ~ / data do woluminu docker o nazwie my-vol

Krok 1. Dołącz wolumin do „tymczasowego” pojemnika. W tym celu uruchom w terminalu to polecenie:

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

Krok 2. Skopiuj zawartość ~ / data do my-vol . W tym celu uruchom to polecenie w nowym oknie terminala:

cd ~/data docker cp . alpine:/data

Spowoduje to skopiowanie zawartości ~ / data do woluminu my-vol . Po skopiowaniu wyjdź z tymczasowego pojemnika.

Namik Hajiyev
źródło