it-roy-ru.com

Как смонтировать локальные тома в докер

Я пытаюсь использовать docker-machine с 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 все идет хорошо, пока не будет предпринята попытка выполнить команду и появится ошибка:

Невозможно запустить контейнер.

Локальные тома не подключены к удаленной машине. Какова рекомендуемая стратегия для монтирования локальных томов с помощью кода веб-приложений?

75
jdcaballerov

Также столкнулся с этой проблемой, и похоже, что локальные тома не монтируются при использовании docker-machine. Взломать решение заключается в 

  1. получить текущий рабочий каталог экземпляра Docker-машины docker-machine ssh <name> pwd

  2. используйте инструмент командной строки, например 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

NB: вам нужно будет ввести пароль для удаленной системы. Вы можете быстро создать его с помощью ssh в удаленной системе и создать пароль.

  1. измените точку монтирования тома в файле docker-compose.yml с .:/app на /root/<name_of_folder>:/app

  2. запустить docker-compose up -d

Обратите внимание: когда изменения вносятся локально, не забудьте повторно запустить rsync для отправки изменений в удаленную систему.

Это не идеально, но это работает. Проблема продолжается https://github.com/docker/machine/issues/179

Другие проекты, которые пытаются решить эту проблему, включают docker-rsync

25
gbozee

Docker-машина автоматически монтирует каталог пользователей ... Но иногда этого просто недостаточно.

Я не знаю насчет docker 1.6, но в 1.8 вы МОЖЕТЕ добавить дополнительное монтирование в docker-machine

Добавить точку монтирования виртуальной машины (часть 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: (НЕ требует остановки машины)

  1. Запустите "Oracle VM VirtualBox Manager"
  2. Щелкните правой кнопкой мыши <machine name> (по умолчанию)
  3. Настройки ...
  4. Общие папки
  5. Папка + значок справа (Добавить в общий доступ)
  6. Путь к папке: <Host dir> (e :)
  7. Имя папки: <mount name> (e)
  8. Проверьте "Auto-mount" и "Make Permanent" (только для чтения, если вы хотите ...) (В настоящее время автоматическое монтирование бессмысленно ...)

Монтирование в boot2docker (часть 2)

Вручную смонтировать в boot2docker :

  1. Существуют различные способы входа в систему, используйте «Показать» в «Oracle VM VirtualBox Manager» или ssh/PuTTY в докер по IP-адресу docker-machine ip default и т.д.
  2. Sudo mkdir -p <local_dir>
  3. Sudo mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>

Но это хорошо только до тех пор, пока вы не перезагрузите машину, а затем монтирование будет потеряно ...

Добавление автомонтирования в boot2docker

Пока зашли в машину

  1. Редактировать/создать (как root) /mnt/sda1/var/lib/boot2docker/bootlocal.sh, sda1 может отличаться для вас ...
  2. Добавлять

    mkdir -p <local_dir>
    mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>
    

С этими изменениями у вас должна появиться новая точка монтирования. Это один из немногих файлов, который я могу найти, он вызывается при загрузке и является постоянным. Пока не будет лучшего решения, это должно работать.


Старый метод: Менее рекомендуется , но оставлен как альтернатива

  • Редактировать (как root) /mnt/sda1/var/lib/boot2docker/profile, sda1 может отличаться для вас ...
  • Добавлять

    add_mount() {
      if ! grep -q "try_mount_share $1 $2" /etc/rc.d/automount-shares ; then
        echo "try_mount_share $1 $2" >> /etc/rc.d/automount-shares
      fi
    }
    
    add_mount <local dir> <mount name>
    

В качестве в крайнем случае , вы можете выбрать несколько более утомительную альтернативу и просто изменить образ загрузки.

  • 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

89
Andy

В настоящий момент я не вижу способа монтировать тома на компьютерах, поэтому сейчас подход заключается в том, чтобы как-то скопировать или синхронизировать нужные файлы на машине.

Есть разговоры о том, как решить эту проблему в репозитории github на Docker-машине. Кто-то сделал pull request внедряющий 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

14
claudevandort

Если вы выберете опцию rsync с помощью docker-machine, вы можете объединить ее с помощью команды docker-machine ssh <machinename> следующим образом:

rsync -rvz --rsh='docker-machine ssh <machinename>' --progress <local_directory_to_sync_to> :<Host_directory_to_sync_to>

Он использует этот формат команды rsync, оставляя Host пустым: 

rsync [OPTION]... SRC [SRC]... [[email protected]]Host:DEST

( http://linuxcommand.org/man_pages/rsync1.html )

4
dmh

С октября 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

2
Jorge

Просто подумал, что упомянул, что я использую 18.03.1-ce-win65 (17513) в Windows 10, и я заметил, что если вы ранее делили диск и кэшировали учетные данные, то после изменения пароля у вас появится окно настройки пароля объемы, установленные в контейнерах как пустые.

Это не указывает на то, что на самом деле происходит то, что теперь он не может получить доступ к общему ресурсу со старыми кэшированными учетными данными Решение в этом сценарии состоит в том, чтобы сбросить учетные данные либо через пользовательский интерфейс (Настройки-> Общие диски), либо чтобы потом отключить совместное использование накопителя и ввести новый пароль.

Было бы полезно, если бы docker-compose выдавал ошибку в таких ситуациях.

0
nrjohnstone

Я предполагаю, что файл run_web.sh находится в том же каталоге, что и ваш файл docker-compose.yml. Тогда команда должна быть command: /app/run_web.sh.

Если Dockerfile (который вы не раскрываете) не позаботится о помещении файла run_web.sh в образ Docker.

0
Thomasleveil

После суммирования постов здесь прикреплен обновленный скрипт, чтобы создать дополнительную точку монтирования хоста и автомонтировать при перезапуске 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'
0
Jesse

Наконец, выяснили, как обновить Windows Docker Toolbox до v1.12.5 и сохранить работоспособность томов, добавив общую папку в менеджер Oracle VM VirtualBox и отключив преобразование пути. Если у вас Windows 10+, то лучше использовать более новую версию Docker для Windows.

1й апгрейд Pain:

  1. Сначала удалите VirtualBox.
    • Да, это может сломать вещи в других инструментах, таких как Android Studio. Спасибо Докер :(
  2. Установите новую версию Docker Toolbox.

Пример базы данных Redis: redis: image: redis:Alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw"

В Docker Quickstart Terminal ....

  1. выполните docker-machine stop default - убедитесь, что VM взломан

В Oracle VM VirtualBox Manager ...

  1. Добавлена ​​общая папка в default VM через или командную строку
    • D:\Projects\MyProject\db => /var/db

В docker-compose.yml...

  1. Отображенный том redis как: "/var/db/redis:/data:rw"

В Docker Quickstart Terminal ....

  1. Установить COMPOSE_CONVERT_WINDOWS_PATHS=0 (для версии Toolbox> = 1.9.0)
  2. запустите docker-machine start default, чтобы перезапустить ВМ.
  3. cd D:\Projects\MyProject\
  4. docker-compose up должен работать сейчас. 

Теперь создает базу данных Redis в D:\Projects\MyProject\db\redis\dump.rdb

Зачем избегать относительных путей к хосту?

Я избегал относительных путей к хостам для Windows Toolbox, поскольку они могут вводить недопустимые символы '\'. Это не так приятно, как использование путей относительно docker-compose.yml, но по крайней мере мои коллеги-разработчики могут легко это сделать, даже если их папка проекта находится где-то в другом месте, без необходимости взламывать файл docker-compose.yml (плохо для SCM).

Оригинальный выпуск

К вашему сведению ... Вот исходная ошибка, которую я получил, когда использовал «Чистые относительные пути», которые раньше просто работали в старых версиях. Раньше мое отображение объема было просто "./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

Это ломается по двум причинам ..

  1. Он не может получить доступ к D:
  2. Пути тома не могут содержать символы \
    • docker-compose добавляет их, а затем обвиняет вас в этом !! 
    • Используйте COMPOSE_CONVERT_WINDOWS_PATHS=0, чтобы остановить эту ерунду.

Я рекомендую документировать ваше дополнительное отображение VM общих папок в файле docker-compose.yml, поскольку вам может потребоваться снова удалить VirtualBox и сбросить общую папку, и в любом случае ваши коллеги разработчики будут любить вас за это.

0
Tony O'Hagan

Я использую docker-машину 0.12.2 с диском virtualbox на моей локальной машине. Я обнаружил, что есть каталог /hosthome/$(user name), откуда у вас есть доступ к локальным файлам.

0
Benjamin Slabbert