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

我正在尝试使用docker-compose的docker-machine。 文件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:没有这样的文件或目录

本地卷不安装到远程机器。 build议使用webapps代码安装本地卷的策略是什么?

也遇到了这个问题,它看起来像使用docker-machine时本地卷不挂载。 黑客解决scheme是

  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快速创build一个到远程系统并创build一个密码。

  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

Docker-machine自动安装用户目录… 链接但有时这还不够。

我不知道泊坞窗1.6,但在1.8你可以添加一个额外的装载docker机

添加虚拟机安装点(第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. 文件夹path: <host dir> (e 🙂
  7. 文件夹名称: <mount name> (e)
  8. 检查“自动安装”和“永久”(只读,如果你想…)(目前自动安装是毫无意义的…)

安装在boot2docker(第2部分)

手动安装在boot2docker中

  1. 有多种方式login,使用“Oracle VM VirtualBoxpipe理器”中的“显示”,或通过IP地址docker-machine ip default等ssh /腻子到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

login到机器中

  1. 编辑/创build(以root身份) /mnt/sda1/var/lib/boot2docker/bootlocal.sh可能会因您而异…
  2.  mkdir -p <local_dir> mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir> 

有了这些更改,您应该有一个新的挂载点。 这是我能find的在启动时调用的几个文件之一,并且是持久的。 直到有一个更好的解决scheme,这应该工作。


旧方法: 不太推荐 ,但留作替代

  • 编辑(以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> 

作为最后的手段 ,你可以采取稍微更乏味的select,你可以修改启动镜像。

  • 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
  • 在最后的fi之前添加try_mount_share <local_dir> <mount_name>行。 例如

     try_mount_share /ee 

    只要确保不要设置任何需要的操作系统,比如/ bin等等。

  • docker build -t boot2docker . #这将需要大约一个小时的第一次:(
  • docker run --rm boot2docker > boot2docker.iso
  • 备份旧的boot2docker.iso并将其复制到〜/ .docker / machine / machines /

这是行得通的,只是漫长而复杂的

docker版本1.8.1,docker机器版本0.4.0

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

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

由于它还没有发布,现在我build议,如果你有你的代码托pipe在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 

更新:进一步看,我发现该function已经在最新的二进制文件中可用,当你得到它们,你将能够复制你的本地项目运行一个像这样的命令:

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

作为一般forms:

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

所以你可以复制文件,到和机器之间。

干杯!1

如果你select了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

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

我假设run_web.sh文件docker-compose.yml文件在同一个目录下。 然后该命令应该是command: /app/run_web.sh

除非Dockerfile (你没有公开)负责把run_web.sh文件放到Docker镜像中。

在这里总结post后,附上更新后的脚本,以便在Virtualbox重启时创build额外的主机挂载点和自动挂载。 工作环境简述如下: – 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' 

最后想出了如何将Windows Docker Toolbox升级到v1.12.5,并通过在Oracle VM VirtualBoxpipe理器中添加共享文件夹并禁用path转换来保持我的卷工作。 如果你有Windows 10+,那么你最好使用较新的Docker for Windows。

第一次升级疼痛:

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

Redis数据库示例: redis: image: redis:alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw"

在Docker快速入门terminal….

  1. 运行docker docker-machine stop default – 确保虚拟机有问题

在Oracle VM VirtualBox Manager中…

  1. 通过或命令行在default VM中添加共享文件夹
    • D:\Projects\MyProject\db => /var/db

docker-compose.yml

  1. 将redis卷映射为: "/var/db/redis:/data:rw"

在Docker快速入门terminal….

  1. 设置COMPOSE_CONVERT_WINDOWS_PATHS=0 (对于工具箱版本> = 1.9.0)
  2. 运行docker-machine start default重启虚拟机。
  3. cd D:\Projects\MyProject\
  4. docker-compose up现在应该工作。

现在在D:\Projects\MyProject\db\redis\dump.rdb创buildredis数据库

为什么避免相对主机path?

避免了Windows Toolbox的相对主机path ,因为它们可能会引入无效的“\”字符。 它不如使用相对于docker-compose.ymlpath,但是至less我的开发人员可以轻松地做到这一点,即使他们的项目文件夹是在别处,而无需破解docker-compose.yml文件(对SCM不好)。

原始问题

仅供参考…这是我得到的原始错误,当我用很好的干净的相对path,以前工作得很好的旧版本。 我的卷映射曾经只是"./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. 卷path不能包含\字符
    • docker-compose添加他们,然后指责你!
    • 使用COMPOSE_CONVERT_WINDOWS_PATHS=0来停止这个废话。

我build议在你docker-compose.yml文件中logging你的额外的VM共享文件夹映射,因为你可能需要再次卸载VirtualBox并重置共享文件夹,无论如何,你的同事会爱你。

我在我的本地机器上使用docker-machine 0.12.2和virtualbox驱动器。 我发现有一个目录/hosthome/$(user name)从你有权访问本地文件。

这似乎对我有用

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