Как добавить том в существующий контейнер Docker?
У меня есть контейнер Docker, который я создал, просто установив Docker на Ubuntu и выполнив:
sudo docker run -i -t ubuntu /bin/bash
Я сразу же начал установку Java и некоторых других инструментов, потратил на это некоторое время и остановил контейнер
exit
Затем я захотел добавить том и понял, что это не так просто, как я думал. Если я использую sudo docker -v /somedir run ...
, тогда я получаю новый новый контейнер, поэтому я бы установил Java и сделаю то, что я уже сделал, прежде чем просто достать контейнер с установленным томом.
Вся документация по установке папки с хоста, по-видимому, подразумевает, что установка тома - это то, что можно сделать при создании контейнера. Таким образом, единственный вариант, который я должен избегать переконфигурации нового контейнера с нуля, - это привязать существующий контейнер к хранилищу и использовать его в качестве основы при установке тома.
Действительно ли это единственный способ добавить том в существующий контейнер?
Ответы
Ответ 1
Вы можете зафиксировать свой существующий контейнер (то есть создать новое изображение из изменений контейнеров), а затем запустить его с вашими новыми монтируемыми устройствами.
Пример:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a8f89adeead ubuntu:14.04 "/bin/bash" About a minute ago Exited (0) About a minute ago agitated_newton
$ docker commit 5a8f89adeead newimagename
$ docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash
Если все в порядке, остановите свой старый контейнер и используйте этот новый.
Это оно :)
Ответ 2
Пока да, единственный способ - это отдых. См. Docker Pull Request 8484, когда мы можем ожидать функциональности динамического добавления.
Ответ 3
У нас нет никакого способа добавить том в работающий контейнер, но для достижения этой цели вы можете использовать следующие команды:
Скопируйте файлы/папки между контейнером и локальной файловой системой: -
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Для справки смотрите:
https://docs.docker.com/engine/reference/commandline/cp/
Ответ 4
Жером Петаццони имеет довольно интересное сообщение в блоге о том, как Приложить объема в контейнер, пока он работает. Это не то, что встроено в Docker из коробки, но возможно выполнить.
Как он также указывает
Это не будет работать в файловых системах, которые не основаны на блочных устройствах.
Он будет работать только в том случае, если /proc/mounts правильно отображает блок-устройство node (которое, как мы видели выше, не обязательно верно).
Кроме того, я тестировал это только в своей локальной среде; Я даже не пробовал экземпляр облака или что-то в этом роде
YMMV
Ответ 5
Я успешно смонтировал папку /home/<user-name>
моего хоста в папку /mnt
существующего (не запущенного) контейнера. Вы можете сделать это следующим образом:
-
Откройте файл конфигурации, соответствующий остановленному контейнеру, который можно найти по адресу /var/lib/docker/containers/99d...1fb/config.v2.json
(может быть config.json
для более старых версий докера).
-
Найдите раздел MountPoints
, который в моем случае был пуст: "MountPoints":{}
. Затем замените содержимое на что-то вроде этого (вы можете скопировать правильное содержимое из другого контейнера с правильными настройками):
"MountPoints":{"/mnt":{"Source":"/home/<user-name>","Destination":"/mnt","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/home/<user-name>","Target":"/mnt"},"SkipMountpointCreation":false}}
или то же самое (отформатировано):
"MountPoints": {
"/mnt": {
"Source": "/home/<user-name>",
"Destination": "/mnt",
"RW": true,
"Name": "",
"Driver": "",
"Type": "bind",
"Propagation": "rprivate",
"Spec": {
"Type": "bind",
"Source": "/home/<user-name>",
"Target": "/mnt"
},
"SkipMountpointCreation": false
}
}
- Перезапустите службу Docker:
service docker restart
Это работает для меня с Ubuntu 18.04.1 и Docker 18.09.0
Ответ 6
К сожалению, опция переключателя для монтирования тома находится только в команде run
.
docker run --help
-v, --volume list Bind mount a volume (default [])
Существует способ, которым вы можете обойти это, поэтому вам не придется переустанавливать приложения, которые вы уже настроили в своем контейнере.
- Экспорт контейнера
docker container export -o ./myimage.docker mycontainer
- Импорт как изображение
docker import ./myimage.docker myimage
- Затем
docker run -i -t -v /somedir --name mycontainer myimage /bin/bash
Ответ 7
Лучший способ - скопировать все файлы и папки в каталог в вашей локальной файловой системе: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
SRC_PATH
находится на контейнере DEST_PATH
находится на локальном DEST_PATH
Затем выполните docker-compose down
присоедините том к тому же DEST_PATH
и запустите Docker-контейнеры, используя docker-compose up -d
Добавьте объем, следуя в docker-compose.yml
volumes:
- DEST_PATH:SRC_PATH
Ответ 8
Замечание по использованию контейнеров Docker Windows после того, как мне пришлось долго искать эту проблему!
Condiditions:
- Windows 10
- Docker Desktop (последняя версия)
- использование Docker Windows Container для образа microsoft/mssql-server-windows -d eveloper
Проблема:
- Я хотел смонтировать словарь хоста в мой контейнер Windows.
Решение как частично различается здесь:
docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer
- перейти к командной оболочке в контейнере
docker exec -it <CONTAINERID< cmd.exe
mkdir DirForMount
docker container stop <CONTAINERID>
docker commit <CONTAINERID> <NEWIMAGENAME>
docker container rm <CONTAINERID>
- создать новый контейнер с новым изображением и объемным монтажом
docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y -v C:\DirToMount:C:\DirForMount <NEWIMAGENAME>
После этого я решил эту проблему на контейнерах Docker Windows.