Как монтировать локальные тома в докерной машине
Я пытаюсь использовать докер-машину с docker-compose. Файл docker-compose.yml имеет следующие определения:
web:
build: .
command: ./run_web.sh
volumes:
- .:/app
ports:
- "8000:8000"
links:
- db:db
- rabbitmq:rabbit
- redis:redis
При запуске docker-compose up -d
все идет хорошо, пока не попытается выполнить команду, и возникает ошибка:
Не удается запустить контейнер b58e2dfa503b696417c1c3f49e2714086d4e9999bd71915a53502cb6ef43936d: [8] Системная ошибка: exec: "./run_web.sh": stat./run_web.sh: нет такого файла или каталога
Локальные тома не подключены к удаленному компьютеру. Какова рекомендуемая стратегия для монтирования локальных томов с кодом webapps?
Ответы
Ответ 1
Также столкнулась с этой проблемой, и похоже, что локальные тома не установлены при использовании док-машины. Решение для взлома -
-
получить текущий рабочий каталог экземпляра docker-machine docker-machine ssh <name> pwd
-
используйте инструмент командной строки, например rsync
, чтобы скопировать папку в удаленную систему.
rsync -avzhe ssh --progress <name_of_folder> [email protected]_ip:<result _of_pwd_from_1>.
Значение по умолчанию pwd равно /root, поэтому приведенная выше команда будет rsync -avzhe ssh --progress <name_of_folder> [email protected]_ip:/root
Примечание: вам нужно будет указать пароль для удаленной системы. Вы можете быстро создать один из ssh в удаленной системе и создать пароль.
-
измените точку монтирования тома в файле docker-compose.yml
с .:/app
до /root/<name_of_folder>:/app
-
run docker-compose up -d
NB, когда изменения сделаны локально, не забудьте перезапустить rsync
, чтобы направить изменения в удаленную систему.
Это не идеальный, но он работает. Проблема продолжается https://github.com/docker/machine/issues/179
Другой проект, который пытается решить эту проблему, включает docker-rsync
Ответ 2
Docker-машина автоматически монтирует каталог пользователей... Но иногда этого просто недостаточно.
Я не знаю насчет докера 1.6, но в 1.8 вы МОЖЕТЕ добавить дополнительное крепление к докеру
Добавить точку монтирования виртуальной машины (часть 1)
CLI: (работает только когда машина остановлена)
VBoxManage sharedfolder add <machine name/id> --name <mount_name> --hostpath <host_dir> --automount
Так что пример в Windows будет
/c/Program\ Files/Oracle/VirtualBox/VBoxManage.exe sharedfolder add default --name e --hostpath 'e:\' --automount
GUI: (НЕ требует остановки машины)
- Запустите "Oracle VM VirtualBox Manager"
- Правый -c lick
<machine name>
(по умолчанию) - Настройки...
- Общие папки
- Значок Folder+ справа (Добавить долю)
- Путь к папке:
<host dir>
(e :) - Имя папки:
<mount name>
(e) - Проверьте "Auto-mount" и "Make Permanent" (только для чтения, если вы хотите...) (Автоматическое монтирование в настоящее время бессмысленно...)
Монтирование в boot2docker (часть 2)
Смонтировать вручную в boot2docker:
- Существуют различные способы входа в систему, использовать "Показать" в "Oracle VM VirtualBox Manager" или ssh/putty в docker по IP-адресу
docker-machine ip default
и т. Д... -
sudo mkdir -p <local_dir>
-
sudo mount -t vboxsf -o defaults,uid='id -u docker',gid='id -g docker' <mount_name> <local_dir>
Но это хорошо только до тех пор, пока вы не перезагрузите машину, а затем монтирование будет потеряно...
Добавление автомонтирования в boot2docker:
Пока зашли в машину
- Отредактируйте/создайте (как пользователь root)
/mnt/sda1/var/lib/boot2docker/bootlocal.sh
, sda1 может отличаться для вас... -
добавлять
mkdir -p <local_dir>
mount -t vboxsf -o defaults,uid='id -u docker',gid='id -g docker' <mount_name> <local_dir>
С этими изменениями у вас должна появиться новая точка монтирования. Это один из немногих файлов, которые я могу найти, он вызывается при загрузке и является постоянным. Пока не будет лучшего решения, это должно работать.
Старый метод: менее рекомендуемый, но оставленный как альтернатива
В крайнем случае, вы можете выбрать более утомительную альтернативу и просто изменить образ загрузки.
-
git -c core.autocrlf=false clone https://github.com/boot2docker/boot2docker.git
-
cd boot2docker
-
git -c core.autocrlf=false checkout v1.8.1
# или ваша подходящая версия - Отредактируйте
rootfs/etc/rc.d/automount-shares
-
Добавьте try_mount_share <local_dir> <mount_name>
прямо перед fi в конце. Например
try_mount_share /e e
Только убедитесь, что вы не установили ничего, что нужно ОС, например, /bin и т.д...
-
docker build -t boot2docker.
# Это займет около часа в первый раз :( -
docker run --rm boot2docker > boot2docker.iso
- Сделайте резервную копию старого boot2docker.iso и скопируйте новый на его место, в ~/.docker/machine/machines/
Это работает, это просто долго и сложно
Docker версии 1.8.1, Docker-машина версии 0.4.0
Ответ 3
В настоящий момент я не могу увидеть какой-либо способ монтирования томов на машинах, поэтому подход к этому моменту должен был как-то скопировать или синхронизировать файлы, которые вам нужны, в машину.
Есть беседы о том, как решить эту проблему на докере-машине github repo. Кто-то сделал запрос , реализующий scp на докер-машине, и он уже слился с мастером, так что это очень вероятно что следующий релиз будет включать его.
Так как он еще не выпущен, я бы порекомендовал, что если ваш код размещен на github, просто клонируйте свое репо перед запуском приложения
web:
build: .
command: git clone https://github.com/my/repo.git; ./repo/run_web.sh
volumes:
- .:/app
ports:
- "8000:8000"
links:
- db:db
- rabbitmq:rabbit
- redis:redis
Обновление: в дальнейшем я обнаружил, что эта функция уже доступна в последних двоичных файлах, когда вы их получите, вы сможете скопировать локальный проект, выполните команду следующим образом:
docker-machine scp -r . dev:/home/docker/project
Это общий вид:
docker-machine scp [machine:][path] [machine:][path]
Таким образом, вы можете копировать файлы с, на и между машинами.
Ура! 1
Ответ 4
Если вы выберете опцию rsync с док-станцией, вы можете объединить ее с командой docker-machine ssh <machinename>
следующим образом:
rsync -rvz --rsh='docker-machine ssh <machinename>' --progress <local_directory_to_sync_to> :<host_directory_to_sync_to>
Он использует этот формат команды rsync, оставляя HOST
blank:
rsync [OPTION]... SRC [SRC]... [[email protected]]HOST:DEST
(http://linuxcommand.org/man_pages/rsync1.html)
Ответ 5
С октября 2017 года существует новая команда для docker-machine, которая делает свое дело, но перед выполнением убедитесь, что в каталоге ничего нет, иначе она может потеряться:
docker-machine mount <machine-name>:<guest-path> <host-path>
Проверьте документы для получения дополнительной информации: https://docs.docker.com/machine/reference/mount/
PR с изменениями: https://github.com/docker/machine/pull/4018
Ответ 6
Наконец, выяснилось, как обновить Windows Docker Toolbox до версии 1.1.5 и сохранить мои тома, добавив общую папку в диспетчер Oracle VM VirtualBox
и отключив преобразование пути. Если у вас Windows 10+, то лучше использовать новый Docker для Windows.
1-ая обновление Боль:
- Сначала удалите VirtualBox.
- Да, это может сломать материал в других инструментах, таких как Android Studio. Спасибо Docker: (
- Установите новую версию Docker Toolbox.
Пример базы данных Redis:
redis:
image: redis:alpine
container_name: redis
ports:
- "6379"
volumes:
- "/var/db/redis:/data:rw"
В терминале быстрого запуска Docker....
- run
docker-machine stop default
- Убедитесь, что виртуальная машина повреждена.
В Oracle VM VirtualBox Manager...
- Добавлена общая папка в
default
VM через или в командной строке
-
D:\Projects\MyProject\db
= > /var/db
В docker-compose.yml
...
- Отображаемый объем текста:
"/var/db/redis:/data:rw"
В терминале быстрого запуска Docker....
- Установить
COMPOSE_CONVERT_WINDOWS_PATHS=0
(для версии Toolbox >= 1.9.0)
- запустите
docker-machine start default
, чтобы перезапустить виртуальную машину.
-
cd D:\Projects\MyProject\
-
docker-compose up
должен работать сейчас.
Теперь создается база данных redis в D:\Projects\MyProject\db\redis\dump.rdb
Зачем избегать относительных путей хоста?
Я избегал относительных хостов для Windows Toolbox, поскольку они могут вводить неверные символы "\". Это не так хорошо, как использование путей относительно docker-compose.yml
, но, по крайней мере, мои коллеги-разработчики могут легко это сделать, даже если их папка проекта находится в другом месте без взлома файла docker-compose.yml
(плохо для SCM).
Оригинальная проблема
FYI... Вот исходная ошибка, которую я получил, когда использовал хорошие чистые относительные пути, которые раньше отлично работали для старых версий. Мое отображение томов было просто "./db/redis:/data:rw"
ERROR: for redis Cannot create container for service redis: Invalid bind mount spec "D:\\Projects\\MyProject\\db\\redis:/data:rw": Invalid volume specification: 'D:\Projects\MyProject\db\redis:/data
Это происходит по двум причинам.
- Он не может получить доступ к
D:
диску
- Пути томов не могут включать символы
\
-
docker-compose
добавляет их, а затем обвиняет вас в этом!
- Используйте
COMPOSE_CONVERT_WINDOWS_PATHS=0
, чтобы остановить эту бессмыслицу.
Я рекомендую документировать ваше дополнительное сопоставление общих папок VM в вашем файле docker-compose.yml
, поскольку вам может понадобиться снова удалить VirtualBox и reset общую папку, и в любом случае ваши коллеги-разработчики будут вас любить.
Ответ 7
Я предполагаю, что файл run_web.sh
находится в том же каталоге, что и ваш файл docker-compose.yml
. Тогда команда должна быть command: /app/run_web.sh
.
Если Dockerfile
(который вы не раскрываете), позаботится о том, чтобы вставить файл run_web.sh
в изображение Docker.
Ответ 8
После суммирования сообщений здесь добавьте обновленный script, чтобы создать дополнительную точку монтирования узла и автомонтировать при перезапуске Virtualbox. Краткое описание рабочей среды:
- Windows 7
- версия docker-machine.exe 0.7.0
- VirtualBox 5.0.22
#!env bash
: ${NAME:=default}
: ${SHARE:=c/Proj}
: ${MOUNT:=/c/Proj}
: ${VBOXMGR:=C:\Program Files\Oracle\VirtualBox\VBoxManage.exe}
SCRIPT=/mnt/sda1/var/lib/boot2docker/bootlocal.sh
## set -x
docker-machine stop $NAME
"$VBOXMGR" sharedfolder add $NAME --name c/Proj --hostpath 'c:\' --automount 2>/dev/null || :
docker-machine start $NAME
docker-machine env $NAME
docker-machine ssh $NAME 'echo "mkdir -p $MOUNT" | sudo tee $SCRIPT'
docker-machine ssh $NAME 'echo "sudo mount -t vboxsf -o rw,user $SHARE $MOUNT" | sudo tee -a $SCRIPT'
docker-machine ssh $NAME 'sudo chmod +x /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
docker-machine ssh $NAME 'sudo /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
#docker-machine ssh $NAME 'ls $MOUNT'
Ответ 9
Я использую docker-machine 0.12.2 с виртуальным дисководом на моей локальной машине. Я обнаружил, что есть каталог /hosthome/$(user name)
, из которого у вас есть доступ к локальным файлам.
Ответ 10
Просто подумал, что упомяну, что я использую 18.03.1-ce-win65 (17513) в Windows 10, и я заметил, что если вы ранее делили диск и кэшировали учетные данные, то после изменения пароля у вас появится окно настройки пароля объемы, установленные в контейнерах как пустые.
Это не указывает на то, что на самом деле происходит то, что теперь он не может получить доступ к общим со старыми кэшированными учетными данными. Решение в этом сценарии состоит в том, чтобы сбросить учетные данные либо через пользовательский интерфейс (Settings-> Общие диски), либо отключить совместное использование арендуемого диска и ввести новый пароль.
Было бы полезно, если бы docker-compose выдавал ошибку в таких ситуациях.
Ответ 11
Все остальные ответы были хорошими для того времени, но теперь (Docker Toolbox v18.09.3) все работает "из коробки". Вам просто нужно добавить общую папку в VirtualBox VM.
Docker Toolbox автоматически добавляет C:\Users
в общую папку /c/Users
под виртуальной машиной Linux (используя функцию общих папок Virtual Box), поэтому, если ваш файл docker-compose.yml
находится где-то по этому пути, и вы монтируете только каталоги хост-машины по этому пути - все должно работать из коробки.
Например:
C:\Users\username\my-project\docker-compose.yml
:
...
volumes:
- .:/app
...
.
путь будет автоматически преобразован в абсолютный путь C:\Users\username\my-project
а затем в /c/Users/username/my-project
. И именно так этот путь рассматривается с точки зрения виртуальной машины Linux (вы можете проверить это: docker-machine ssh
а затем ls/c/Users/username/my-project
). Итак, окончательное монтирование будет /c/Users/username/my-project: /app
.
Все работает прозрачно для вас.
Но это не работает, если ваш путь монтирования хоста не находится в C:\Users
path. Например, если вы поместите тот же docker-compose.yml
D:\dev\my-project
.
Это можно легко исправить, хотя.
- Остановите виртуальную машину (
docker-machine stop
). -
Откройте Virtual Box GUI, откройте Настройки виртуальной машины с именем default
, откройте раздел Shared Folders
и добавьте новую общую папку:
- Путь к папке:
D:\dev
- Название папки:
d/dev
Нажмите OK
дважды и закройте графический интерфейс Virtual Box.
- Запустите виртуальную машину (
docker-machine start
).
Все это. Все пути к хост-машине под D:\dev
теперь должны работать в монтировании docker-compose.yml
.
Ответ 12
Кажется, это работает для меня
volumes:
- $PWD/drupal-prod-files:/drupal-prod-files