Який правильний спосіб додавати дані до існуючого іменованого тому в Docker?


88

Я використовував Docker по-старому, з контейнером об’єму:

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

Але тепер я перейшов на новий спосіб, створивши іменований том:

 docker volume create --name my-jenkins-volume 

Я прив’язав цей новий том до нового контейнера Jenkins. Єдине, що я залишив - це папка, в якій я зберігаю /var/jenkins_homeсвій попередній контейнер jenkins. (за допомогою docker cp) Тепер я хочу наповнити мій новий іменований том вмістом цієї папки.

Чи можу я просто скопіювати вміст цієї папки /var/lib/jenkins/volume/my-jenkins-volume/_data?

Відповіді:


134

Ви можете, звичайно, скопіювати дані безпосередньо в /var/lib/docker/volumes/my-jenkins-volume/_data, але, роблячи це, ви:

  • Покладаючись на фізичний доступ до хоста докера. Цей прийом не спрацює, якщо ви взаємодієте з віддаленим API докера.

  • Покладання на певний аспект реалізації томів може змінитися в майбутньому, порушуючи всі ваші процеси, які на нього покладаються.

Я думаю, що вам краще покладатися на речі, які ви можете досягти за допомогою API docker, через клієнт командного рядка. Найпростішим рішенням є, мабуть, просто використання допоміжного контейнера, приблизно такого:

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

3
Що стосується вашої другої кулі, ви можете побігти, docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'щоб отримати її фізичне розташування програмно. Все ще не відчуваю себе чудовою ідеєю.
c24w

8
Цей допоміжний контейнер ніколи не потребує фактичного запуску. Досить було б просто створити його, потім запустити, docker cpа потім видалити.
Алекс

Ви не можете зайти в цей контейнер, щоб переглянути результати або змінити файли вручну.
CodeOrElse

3
Зверніть увагу, що перелік /var/lib/docker/volumes/my-jenkins-volume/_dataпід час використання Docker для Mac не працює, оскільки файли зберігаються у віртуальній машині xhyve . Дивіться forums.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
Ортомала Локні,

1
Тут пояснюється правда stackoverflow.com/questions/29762231/…
Зуабі,

32

Ви можете зменшити прийняту відповідь до одного рядка, використовуючи, наприклад

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

1
Мені цікаво, чи може тимчасова природа / tmp створювати ризик, що контейнер може видалити ваші дані до завершення cp? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
thurt

1
Посилання насправді не уточнює термін служби файлів у / tmp. Я заявляю: "Програми не повинні припускати, що будь-які файли або каталоги в / tmp зберігаються між викликами програми." що означає, що файли виживуть, але це гарантія. Параметр -v для docker створить каталог у контейнері, якщо такий не існує, тому зміна / tmp / src на / src спрацює, якщо вас турбує цей потенційний стан перегонів. Я відредагую відповідь, щоб відобразити це, оскільки немає мінусів.
headdab

3
не -v `pwd`:/srcозначає, що команда працює на хості? (Як можна зіставити хост, pwdякщо це, наприклад, інша машина? - не може.) Якщо команда докера не працює на хості, це не працює. Я вважаю, що тому у нас є docker cp. Здається, це не «шлях» для докера - це лише особливий випадок, який працює лише тоді, коли на хості працює команда docker. Чи правильно я розумію?
Wyck

Так, я думаю, ти маєш рацію. pwdповинен перейти до файлу на хост-машині. З документації монтування докера: "У випадку монтування прив'язки першим полем є шлях до файлу або каталогу на хост-машині."
headdab

1
Таким чином, це не працює , щоб скопіювати ваші локальні файли в контейнер , якщо в віддалений хост, як ви встановлюєте , pwdякі навіть не мають існувати в віддалений хост. Натомість рішення Дмитра Мельничука (create + cp + rm) дійсно копіює локальні в контейнер, незалежно від того, де він запущений.
Хаві Монтеро,

25

Вам не потрібно запускати якийсь контейнер, щоб додати дані до вже існуючого іменованого тому, просто створіть контейнер і скопіюйте дані туди:

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

2
За умови, що вміст busybox насправді не потрібен; Ви можете зробити це за допомогою, hello-worldі це також працює. busyboxстановить 1,22 МБ. Натомість hello-worldце 13,3 кБ. Питання в тому, як ми можемо зробити Dockerfile ВІД нуля, чи могли б ми зробити "створення контейнера докера" з "нічим" як зображенням, оскільки ми хочемо лише "змонтувати" том і ніколи не запускати контейнер?
Хаві Монтеро,

1
+1 для цього рішення поверх голосувала , але правильний синтаксис docker cpєdocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
Marco Dufal

4

Ось кроки для копіювання вмісту ~ / даних у том докера з іменем my-vol

Крок 1. Приєднайте том до "тимчасового" контейнера. Для цього запуску в терміналі виконується ця команда:

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

Крок 2. Скопіюйте вміст ~ / даних у my-vol . Для цього виконайте ці команди у новому вікні терміналу:

cd ~/data docker cp . alpine:/data

Це скопіює вміст ~ / даних у том my-vol . Після копіювання вийдіть з тимчасового контейнера.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.