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

Я пытаюсь использовать докер-машину с 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 в удаленной системе и создать пароль.

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

  2. 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: (НЕ требует остановки машины)

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

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

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

  1. Существуют различные способы входа в систему, использовать "Показать" в "Oracle VM VirtualBox Manager" или ssh/putty в docker по 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

Ответ 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...

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

В docker-compose.yml...

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

В терминале быстрого запуска Docker....

  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).

Оригинальная проблема

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.

Это можно легко исправить, хотя.

  1. Остановите виртуальную машину (docker-machine stop).
  2. Откройте Virtual Box GUI, откройте Настройки виртуальной машины с именем default, откройте раздел Shared Folders и добавьте новую общую папку:

    • Путь к папке: D:\dev
    • Название папки: d/dev

    Нажмите OK дважды и закройте графический интерфейс Virtual Box.

  3. Запустите виртуальную машину (docker-machine start).

Все это. Все пути к хост-машине под D:\dev теперь должны работать в монтировании docker-compose.yml.

Ответ 12

Кажется, это работает для меня

volumes: - $PWD/drupal-prod-files:/drupal-prod-files