用Docker在OS X上设置开发环境的正确方法是什么?


94

介绍

我想不出一种使用Docker和Boot2Docker在OS X上设置开发环境的好方法。我遇到的问题是如何管理源代码,以便:

  1. 我可以使用已经安装的工具(文本编辑器,IDE,git等)在OS X上修改代码。
  2. 这些修改反映在Docker容器中,因此,如果我重新运行测试或刷新网页,则可以立即看到所做的更改。

从理论上讲,通过将我的源代码安装为一个卷可以很容易地做到这一点:

docker run -it -v /path/to/my/source/code:/src some-docker-image

不幸的是,这有两个主要问题,使其在OS X上完全无法使用:

问题1:在VirtualBox上安装的卷(使用vboxsf)非常慢

例如,如果源代码是Docker映像的一部分,这是Jekyll编译我的主页需要多长时间:

> docker run -it brikis98/yevgeniy-brikman-homepage:v1 bash

root@7aaea30d98a1:/src# time bundle exec jekyll build

[...]

real    0m7.879s
user    0m7.360s
sys     0m0.600s

这是完全相同的Docker映像,除了这次,我从OS X挂载了源代码:

> docker run -it -v $(pwd):/src brikis98/yevgeniy-brikman-homepage:v1 bash

root@1521b0b4ce6a:/src# time bundle exec jekyll build

[...]

real    1m14.701s
user    0m9.450s
sys     0m3.410s

问题2:文件监视功能已损坏

SBT,Jekyll和grunt中的默认监视机制使用诸如inotify之类的技术,如果它们在Docker容器中运行并且在OS X中对已安装的文件夹进行了更改,则这些技术将不起作用。

我尝试过的解决方法

我搜索了解决方案(包括SO上的所有解决方案),并尝试了其中的一些解决方案,但没有找到成功的解决方案:

  1. 将Boot2Docker切换为使用NFS,但速度同样慢。
  2. 我尝试了Vagrant + NFS,而且速度也一样慢。
  3. 我尝试了Samba挂载,但是该文件夹在Docker容器中始终显示为空。
  4. 我尝试使用Unison文件系统,该系统可以短暂地同步文件,但随后一直显示连接错误
  5. 在Jekyll中启用了轮询功能,但这大大增加了延迟,直到我的更改被提取为止。
  6. 我尝试了Dinghy,它是“在带有Vagrant的OS X上更快,更友好的Docker”,并得到了一些改进。Jekyll的编译速度要慢2-3倍,而不是Jekyll慢10-15倍。更好,但仍然不太实用。

有没有人找到一个切实可行的解决方案,并允许您使用Docker和OS X高效地开发代码?

更新:终于解决了!

我终于找到了一个使用Boot2Docker + rsync似乎很有成效的解决方案。我已经在我自己的答案以及一个名为docker-osx-dev的开源项目中捕获了有关如何进行设置的详细信息。


您已经尝试过将OS X的官方Docker安装程序与NFS一起使用吗?AFAIK这不仅是OS X上的Docker的问题,还是OS X上具有较大代码库的基于Vagrant的开发的问题我们有类似的问题,但使用Vagrant)。我发现NFS是唯一可行且可接受的解决方案。
詹姆斯·米尔斯

@JamesMills:我按照官方说明安装了Docker和Boot2Docker。是否有关于设置NFS的官方说明?我只是在GitHub上找到了它们,使用它们后,它似乎并没有更快。您是如何设置NFS的?
叶夫根尼·布里克曼


6
使用Docker的正确方法是在本地运行Linux而不是OS X,或者在Linux VM内完成所有开发工作。“ boot2docker”集成是一个很大的丑陋的hack,除了造成混乱和失望之外,什么也不做。
幼虫

7
@larsks:这没有帮助。
Yevgeniy Brikman 2015年

Answers:


46

我决定添加自己的答案以及到目前为止找到的最佳解决方案。如果找到更好的选择,我将进行更新。

迄今为止最好的解决方案

我发现在OS X上使用Docker设置生产性开发环境的最佳解决方案是:Boot2Docker + Rsync。使用rsync,可直接在OSX上运行Docker容器中的构建时间!此外,该文件观察家代码并没有需要轮询(inotify因为rsync使用普通文件夹的作品),所以热重装是几乎一样快。

有两种设置方法:自动安装和手动安装。

自动安装

我已经将使用Rsync设置Boot2Docker的所有步骤打包到一个名为docker -osx-dev的开源项目中。代码有点粗糙,但是我已经成功使用了几周,可以轻松地在具有3个不同技术堆栈的3个项目之间切换。试试看,报告错误,并提交一些PR!另外,有关更多信息,请参阅我的博客文章“ 在OS X上使用Docker进行高效的开发环境”

手动设定

  1. 安装Boot2Dockerbrew install boot2docker
  2. 运行Boot2Docker,但禁用VirtualBox共享文件夹:boot2docker init && boot2docker start --vbox-share=disable
  3. 运行boot2docker shellinit并将其打印出的环境变量复制到您的~/.bash_profile文件中。
  4. 在Boot2Docker VM上安装rsync :boot2docker ssh "tce-load -wi rsync"
  5. 在Boot2Docker VM上创建所需的基本文件夹,并为其正确设置权限。例如,如果/foo/bar要从OS X 同步文件夹,则需要/foo/bar在Boot2Docker VM上创建:boot2docker ssh "mkdir -p /foo/bar && chown -R docker /foo/bar"
  6. 运行的rsync同步文件到Boot2Docker VM: rsync --archive --rsh="ssh -i $HOME/.ssh/id_boot2docker -o StrictHostKeyChecking=no" /foo/bar docker@dockerhost:/foo。在rsync文档中检查您可能要启用的各种设置,例如在同步时--exclude .git用于排除.git文件夹。
  7. 使用文件观察器使文件保持同步。例如,您可以使用通过brew install fswatch管道传递到rsync的fswatch()。
  8. 在这一点上,您应该能够docker run启动Docker容器并使用该-v标志挂载您要同步的文件夹:docker run -v /foo/bar:/src some-docker-image
  9. 照常更新OS X上的代码。更改应使用rsync迅速传播,常规文件监视程序代码应照常进行更改(即,使用inotify),并且构建应快速运行,因为所有文件都是“本地”到容器的。
  10. 如果您需要测试运行中的网站,请运行boot2docker ip命令以查找其使用的IP。

感谢分享!当他们说rsync是“仅单向”时,是否表示我不能使用OS X文件系统在两个容器之间共享文件?示例:容器1监视源文件并编译二进制文件,容器2用于运行已编译的二进制文件(在此示例中使用Haskell)。
Nicolas Hery 2015年

1
@NicolasHery:我的理解是rsync会将更改从OS X复制到Docker容器,但不会反过来。因此,由Docker容器生成的任何文件(例如,已编译的二进制文件)在OS X中都不可见。但是,如果这些文件是在标记为的文件夹中生成的VOLUME,则可以使用来授予另一个容器对该卷的访问权限--volumes-from旗。我还没有尝试过,但是我怀疑它会起作用。
叶夫根尼·布里克曼

1
好答案。您可以为docker -machine(github.com/docker/machine)创建一个驱动程序,该驱动程序为您完成大部分样板工作。
dom

1
@dom:我喜欢这个主意,但是您知道如何为docker-machine创建驱动程序吗?是将请求拉到存储库中的唯一方法,还是可以在外部创建驱动程序?
叶夫根尼·布里克曼

1
本教程对Windows上的最新1.9.1版本仍然有效吗?我可以使用它,还是Docker已经为该“问题”提供了新的解决方案?

18

更新:既然Mac的docker处于beta版且具有非hack功能,那么对于本地开发而言,采用这种方法可能会更合理,而无需撰写本文的大量hack和解决方法。

不要。我知道这不是您可能想要的答案,但是请诚实地评估尝试获取本地源代码+ dockerized执行与仅在OSX上进行本地开发相比的成本/收益。

在某些时候,所有问题,设置工作和操作难点都可能得到很好的解决,但是到目前为止,我对此的看法是净亏损。

问题1:Virtual Box(使用vboxfs)上的已装入卷非常慢

稍等片刻,这几乎肯定会改善。

问题2:文件监视功能已损坏

我不确定是否会在不久的将来对此进行修复。如果这种功能对您的开发工作流程至关重要,那么我认为这是一个突破。与仅使用rbenv / bundler管理您的jekyll / ruby​​安装并像过去十年来人们成功所做的那样,在OSX上本地运行它们相比,这不值得进行大量的研发工作。

就像“云”零参与我的本地开发设置一样,此刻,docker赢得了测试/登台/部署以及运行数据库和其他第三方组件的胜利,但是我实际编写的应用程序却可以直接运行在OSX上。


1
我同意那个。我们在OSX上进行开发,并直接在系统内部运行应用程序(实时重新加载等)。然后,在应用程序完成后,我们将其进行泊坞测试,测试和生产。
ItalyPaleAle 2015年

4
嗯,这有点令人失望。在舞台/生产环境中,我一直都持平价。正如我在OS X上编写代码时一样,这个开发人员总是离群的。我将再努力一点,看看是否可以使我工作。
Yevgeniy Brikman 2015年

彼得,您今天仍然认为这个答案仍然有效吗?线下仅几个月,但考虑到@Yevgeniy的项目以及现在已解决的2个问题,也许成本/收益现在已经值得了!是不是
cregox 2015年

1
这是个人喜好。我仍然不会对此感到困惑,因为我作为顾问跳入的项目数量之多。如果我是一个全职的工作人员,主要在同一个项目上工作数周/数月,那么可能值得设置rsync / fswatch东西。
彼得·里昂斯

Docker Toolbox是当今正确的解决方法,因为如果您使用自制软件或其他软件包管理器,则docker工具版本将不同步,除非它们遵循作为docker toolbox的版本控制。
塔科

12

适用于Mac和Windows的Docker将是在OS X(和Windows)上使用Docker进行开发的最终方式。该软件是Docker产品,是“一个集成的,易于部署的环境,用于从Mac或Windows构建,组装和交付应用程序。” 它声称能够解决OP提出的问题。从其 2016年3月24日公告

  • 更快,更可靠:不再需要VirtualBox!Docker引擎在Mac OS X上的xhyve虚拟机之上或Windows上的Hyper-V VM上的Alpine Linux发行版中运行,该VM由Docker应用程序管理。您不需要docker-machine即可在Mac和Windows上运行Docker。
  • 工具集成:Docker for Mac是Mac应用程序,Docker for Windows是Windows应用程序,包括本机用户界面和自动更新功能。Docker工具集捆绑在一起:Docker命令行,Docker Compose和Docker Notary命令行。
  • 您的代码和数据的卷挂载:卷数据访问可以正常进行,包括文件更改通知(在Mac上,inotify现在可以在容器中无缝地用于卷挂载目录)。这样就可以进行“容器内”开发的编辑/测试周期。
  • 轻松访问本地主机网络上正在运行的容器:Mac和Windows的Docker包含一个用于容器的DNS服务器,并与Mac OS X和Windows网络系统集成。在Mac上,即使连接到非常严格的公司VPN,也可以使用Docker。
  • Mac的Docker是从头开始构建的,能够适应OS X沙箱安全模型,我们正在与Apple紧密合作以实现这一目标。

我前几天刚看到它,它看起来确实是迄今为止最有希望的解决方案。我很高兴能在Beta版发布后试用一下,如果效果良好,我将其更改为正式接受的答案。
Yevgeniy Brikman

4
不幸的是,目前的测试版本(1.11.0-β7的)似乎是一样缓慢,因为其他的方法,所以它可能需要一段时间,直到这是可行的使用forums.docker.com/t/...
walterra

3

免责声明:我可能是有偏见的,因为我是docker-sync的作者。

我可能尝试了这里命名的所有解决方案,包括更多解决方案(请参见compersion https://github.com/EugenMayer/docker-sync/wiki/Alternatives-to-docker-sync),但是它们基本上要么在性能(大多数)或在docker计算机上使用(或未执行)。

http://docker-sync.io的构建是为了合并所有解决方案并提供最佳策略(实施几种,您可以选择)。

它可以与rsync(1路同步)一起使用,其中包括对用户的权限修复,以及与统一(2路同步)一起使用。它既不会迫使您进入docker-machine或特定的虚拟机管理程序,也不需要您拥有适用于Mac的docker。它适用于所有人。

性能EugenMayer / docker-sync / wiki / 4.-Performance不受影响,就好像您根本没有共享。

docker-sync及其变更观察器经过优化,可以处理包含12k文件的项目,而不会出现问题。

试试看,如果您愿意,我很想听听反馈!


2

我感觉到你了!我想我已经尝试了几乎所有您尝试过的方法,但不幸的是它仍然很慢。然后我遇到了这样的评论https://github.com/boot2docker/boot2docker/issues/64#issuecomment-70689254建议使用Vagrant和Parallels而不是Virtualbox。这使我可以使用nfs,并且确实为我的项目(Drupal)带来了显着的性能提升。

这是流浪者文件。您需要做的就是安装vagrant,将其复制到一个名为Vagrantfile的文件中,并将其放在某个文件夹中。转到该文件夹​​,然后执行一个vagrant up代替正常的boot2docker的操作。

Vagrant.configure(2) do |config|
  config.vm.box = "parallels/boot2docker"

  config.vm.network "forwarded_port", guest: 80, host: 80

  config.vm.synced_folder(
    "/Users/dicix/work/www", "/vagrant",
    type: 'nfs',
    nfs_udp: true,
    mount_options: %w[actimeo=2],
    bsd__nfs_options: %w[alldirs maproot=root:wheel]
  )
end

我假设这需要并行安装?
叶夫根尼·布里克曼

2

我还将Vagrant与parallels和boot2docker(https://github.com/Parallels/boot2docker-vagrant-box)结合使用。对我而言,发展从未如此简单。docker-compose与大型安装程序配合使用时效果很好。我并没有感到延迟或大量资源消耗。

这是我的Vagrantfile样子:

Vagrant.configure(2) do |config|

  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.box = "parallels/boot2docker"

  config.vm.synced_folder "/Users", "/Users", type: "nfs", mount_options: ["nolock", "vers=3", "udp"], id: "nfs-sync"

end

1

我已经在OS X(2011年中期的Macbook Air)+ Boot2Docker + Docker-compose环境中进行开发了几个星期。尚未遇到主要的性能问题,但是在开发时我避免运行任何形式的构建(为什么不使用类似的东西jekyll serve --skip-initial-build?)。这是docker-compose.yml我正在使用的示例文件:

docker-compose.yml:

test:
  build: .
  volumes:
    - ./client:/src/client
    - ./server:/src/server
    - ./test:/src/test
  command: nodemon --exec jasmine-node -- test/ --verbose --autotest --captureExceptions --color
  environment:
    - DEBUG=*

Dockerfile:

FROM node:0.12

RUN mkdir -p /src
WORKDIR /src

ENV PATH=/src/node_modules/.bin:$PATH

# We add package.json first so that we the
# image build can use the cache as long as the
# contents of package.json hasn't changed.

COPY package.json /src/
RUN npm install --unsafe-perm

COPY . /src

CMD [ "npm", "start" ]
EXPOSE 3000

有时我会使用NFS(http://syskall.com/using-boot2docker-using-nfs-instead-of-vboxsf/),但这样做时并没有注意到性能上的巨大差异。

对我来说,docker-compose up test让我的环境轻松运行所带来的便利值得在性能上付出代价(我通常在具有不同堆栈的多个项目上工作)。

PS:nodemon是使用vboxsf的少数文件监视程序之一(请参阅https://github.com/remy/nodemon/issues/419)。


即使我跳过了使用Jekyll进行的初始构建,每次更改文件时也必须重新构建,如果安装了源代码,则仍然需要1-3分钟的时间。这使得不可能进行任何形式的更改和重新加载样式开发。
Yevgeniy Brikman 2015年

@YevgeniyBrikman哦,我当时还不知道:(我想最后一个选择是让您的代码存在于boot2docker VM中,并使用sshfs将其安装在您的主机上。否则,我想您必须等待更好的挂载文件夹性能,以将docker作为开发环境使用
Olivier Lalonde 2015年



-4

此方法是最新的(2015年9月),也是在Mac上进行Docker设置的最简单方法: 链接到这里:

您可以使用Docker Toolbox 链接安装Docker,以链接到此处的说明:

它是一个完整的Docker安装程序包, 其中包括以下Docker工具:

用于运行docker-machine二进制文件的Docker Machine

用于运行docker二进制文件的Docker引擎

Docker Compose用于运行docker-compose二进制文件

Kitematic,Docker GUI,一个为Docker命令行环境预配置的shell

Oracle VM VirtualBox

在此处输入图片说明

工具箱中的内容:

  • Docker客户端
  • Docker机器
  • Docker Compose(仅限Mac)
  • Docker Kitematic
  • 虚拟盒子

3
是的,但是很遗憾,它没有解决最初提出的问题。
尼克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.