如何在docker机器中安装本地卷

问题描述 投票:77回答:10

我正在尝试使用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时一切顺利,直到尝试执行命令并产生错误:

无法启动容器b58e2dfa503b696417c1c3f49e2714086d4e9999bd71915a53502cb6ef43936d:[8]系统错误:exec:“。/ run_web.sh”:stat ./run_web.sh:没有这样的文件或目录

本地卷未安装到远程计算机。什么是使用webapps代码挂载本地卷的推荐策略?

docker dockerfile docker-compose
10个回答
26
投票

还遇到了这个问题,看起来在使用docker-machine时没有安装本地卷。黑客解决方案是

  1. 获取docker-machine实例docker-machine ssh <name> pwd的当前工作目录
  2. 使用像rsync这样的命令行工具将文件夹复制到远程系统 rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:<result _of_pwd_from_1>.

默认的pwd是/ root,所以上面的命令是rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:/root

注意:您需要提供远程系统的密码。您可以通过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


0
投票

刚想到我提到我在Windows 10上一直使用18.03.1-ce-win65(17513)而且我注意到如果你之前共享过一个驱动器并缓存了凭据,一旦你更改密码,docker将开始拥有容器中安装的卷为空白。

它没有表明实际发生的事情是它现在无法使用旧的缓存凭据访问共享。此方案中的解决方案是通过UI(设置 - >共享驱动器)重置凭据,或者禁用然后重新设置驱动器共享并输入新密码。

如果docker-compose在这些情况下出错,那将会很有用。


0
投票

所有其他答案都很好,但现在(Docker Toolbox v18.09.3)开箱即用。您只需要将一个共享文件夹添加到VirtualBox VM中。

Docker Toolbox会自动将 #!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' 添加为虚拟linux机器下的共享文件夹/hosthome/$(user name)(使用Virtual Box共享文件夹功能),因此,如果您的C:\Users文件位于此路径下的某个位置,并且您只在此路径下安装主机的目录 - 所有这些都应该在框。

例如:

/c/Users

docker-compose.yml

C:\Users\username\my-project\docker-compose.yml路径将自动转换为绝对路径... volumes: - .:/app ... ,然后转换为.。这正是从Linux虚拟机的角度来看这条路径的方法(你可以检查它:C:\Users\username\my-project然后/c/Users/username/my-project)。所以,最后的坐骑将是docker-machine ssh

一切都透明地为您服务。

但是,如果主机挂载路径不在ls /c/Users/username/my-project路径下,则此操作无效。例如,如果你在/c/Users/username/my-project:/app下放置相同的C:\Users

这可以很容易地修复。

  1. 停止虚拟机(docker-compose.yml)。
  2. 打开Virtual Box GUI,打开名为D:\dev\my-project的虚拟机设置,打开docker-machine stop部分并添加新的共享文件夹: 文件夹路径:default 文件夹名称:Shared Folders 按两次D:\dev并关闭Virtual Box GUI。
  3. 启动虚拟机(d/dev)。

就这样。 OK下主机的所有路径现在都可以在docker-machine start坐骑中使用。


91
投票

Docker-machine自动挂载用户目录......但有时候这还不够。

我不知道docker 1.6,但在1.8中你可以为docker-machine添加一个额外的mount

Add Virtual Machine Mount Point (part 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. 检查“自动安装”和“永久安装”(只读,如果你想......)(自动安装目前有点无意义......)

Mounting in boot2docker (part 2)

手动挂载在boot2docker中:

  1. 有多种方法可以登录,在“Oracle VM VirtualBox Manager”中使用“Show”,或者通过IP地址docker-machine ip default等使用ssh / putty到docker中...
  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 #or你的合适版本
  • 编辑rootfs/etc/rc.d/automount-shares
  • 在f之前添加try_mount_share <local_dir> <mount_name>线。例如 try_mount_share /e e 请确保不要设置os需要的任何内容,例如/ bin等...
  • docker build -t boot2docker .#这将是第一次约一个小时:(
  • docker run --rm boot2docker > boot2docker.iso
  • 备份旧的boot2docker.iso并将其复制到其位置~~ .docker / machine / machines /

这确实有效,它只是漫长而复杂

docker version 1.8.1,docker-machine version 0.4.0


14
投票

目前我无法真正看到在机器上安装卷的任何方法,因此现在的方法是以某种方式将您需要的文件复制或同步到机器中。

关于如何在docker-machine的github repo上解决这个问题,有conversations。有人做了一个pull request在docker-machine上实现scp并且它已经在master上合并,所以下一个版本很可能会包含它。

由于它尚未发布,现在我建议如果您的代码托管在github上,只需在运行应用程序之前克隆您的repo

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

更新:进一步观察我发现该功能已经在latest binaries中可用,当你获得它们时,你将能够复制运行如下命令的本地项目:

docker-machine scp -r . dev:/home/docker/project

这是一般形式:

docker-machine scp [machine:][path] [machine:][path]

因此,您可以从机器复制文件,在机器之间复制文件。

干杯!1


4
投票

如果您使用docker-machine选择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留空:

rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST

(Qazxswpoi)


3
投票

自2017年10月以来,有一个针对docker-machine的新命令可以完成这项工作,但确保在执行之前目录中没有任何内容,否则它可能会丢失:

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

查看文档以获取更多信息:docker-machine mount <machine-name>:<guest-path> <host-path>

公关与变化:https://docs.docker.com/machine/reference/mount/


1
投票

最后想出了如何将Windows Docker Toolbox升级到v1.12.5并通过在https://github.com/docker/machine/pull/4018管理器中添加共享文件夹并禁用路径转换来保持我的卷工作。如果你有Windows 10+,那么你最好使用较新的Docker for Windows。

第一次升级痛苦:

  1. 首先卸载VirtualBox。 是的,这可能会破坏其他工具,如Android Studio。谢谢Docker :(
  2. 安装新版本的Docker Toolbox。

Redis数据库示例:Oracle VM VirtualBox

在Docker快速启动终端....

  1. 运行qazxsw poi - 确保VM停止运行

在Oracle VM VirtualBox Manager中......

  1. 通过或命令行在 redis: image: redis:alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw" VM中添加了共享文件夹 docker-machine stop default => default

D:\Projects\MyProject\db ......

  1. 映射redis卷:/var/db

在Docker快速启动终端....

  1. 设置docker-compose.yml(工具箱版本> = 1.9.0)
  2. 运行"/var/db/redis:/data:rw"重启VM。
  3. COMPOSE_CONVERT_WINDOWS_PATHS=0
  4. docker-machine start default现在应该工作。

现在在cd D:\Projects\MyProject\中创建redis数据库

为什么要避免相对主机路径

我避免了Windows Toolbox的相对主机路径,因为它们可能会引入无效的'\'字符。它不如使用相对于docker-compose up的路径那么好,但至少我的开发人员可以很容易地做到这一点,即使他们的项目文件夹在别处而不必破解D:\Projects\MyProject\db\redis\dump.rdb文件(对SCM不好)。

原始问题

仅供参考...这是我使用漂亮干净的相对路径时得到的原始错误,这些路径过去常用于旧版本。我的体积映射曾经只是docker-compose.yml

docker-compose.yml

这打破了两个原因..

  1. 它无法访问"./db/redis:/data:rw"驱动器
  2. 卷路径不能包含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文件中记录其他VM共享文件夹映射,因为您可能需要再次卸载VirtualBox并重置共享文件夹,无论如何,您的伙伴开发人员都会爱你。


0
投票

我假设COMPOSE_CONVERT_WINDOWS_PATHS=0文件与docker-compose.yml文件位于同一目录中。然后命令应该是run_web.sh

除非docker-compose.yml(你没有透露)负责将command: /app/run_web.sh文件放入Docker镜像。


0
投票

在此处汇总帖子后,附加更新的脚本,以在Virtualbox重新启动时创建其他主机挂载点和自动挂载。工作环境简述如下: - Windows 7 - docker-machine.exe版本0.7.0 - VirtualBox 5.0.22

Dockerfile

0
投票

我在我的本地机器上使用docker-machine 0.12.2和virtualbox驱动器。我发现有一个目录run_web.sh,您可以从中访问本地文件。

© www.soinside.com 2019 - 2024. All rights reserved.