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

What's the right way to set up a development environment on OS X with Docker?

简介

我想不出使用 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 编译我的 homepage 需要多长时间:

> 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 和 g运行t 中的默认监视机制使用 inotify 等技术,如果它们 运行ning 在 Docker 容器中并且更改是在 OS X 中对安装的文件夹进行的。

我尝试过的解决方法

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

  1. switched Boot2Docker to use NFS,但是一样慢。
  2. 我试过 Vagrant + NFS,那也一样慢。
  3. 我尝试了 Samba mount,但文件夹在 Docker 容器中总是显示为空。
  4. 我尝试使用 Unison file system, which worked briefly to sync files, but then kept showing connection errors
  5. 我启用了 polling in Jekyll,但这显着增加了延迟,直到我的更改被接受。
  6. 我尝试了 Dinghy,"faster, friendlier Docker on OS X with Vagrant" 并获得了 一些 的改进。 Jekyll 编译不是慢 10-15 倍,而是慢 2-3 倍。好多了,但还是不太好用。

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

更新:终于有解决办法了!

我终于找到了一个使用 Boot2Docker + rsync 似乎很有成效的解决方案。我已经在 as well as an open-source project called docker-osx-dev.

中获取了有关如何进行设置的详细信息

更新:现在 docker for mac 处于测试阶段,具有非 hack 功能,走这条路对于本地开发来说可能更合理,没有论文的价值技巧和解决方法。

不要。我知道这不是您可能希望得到的答案,但是请诚实地评估 cost/benefit 尝试获取本地源代码 + docker 化执行与仅在 OSX 上进行本地开发.

在某些时候,所有问题、设置工作和操作痛点都可能得到很好的解决,但就目前而言,我对此的看法是净损失。

Issue #1: Mounted volumes on Virtual Box (which use vboxfs) are extremely slow

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

Issue #2: File watching is broken

我不确定是否会在不久的将来解决这个问题。如果这种类型的功能是您开发工作流程的关键,我会认为这是一个交易破坏者。与仅使用 rbenv/bundler 管理您的 jekyll/ruby 安装并 运行 在 OSX 上本地安装它们相比,这不值得进行重大的研发工作,就像人们过去一直在做的那样十年+.

就像 "the cloud" 零参与我的本地开发设置一样,目前,docker 是 testing/staging/deployment 和 运行ning 数据库和其他的胜利第三方组件,但我实际编码的应用程序 运行 直接 OSX。

我已经在 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=*

Docker文件:

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 来获得我的环境 运行ning 的便利性值得付出性能代价(我经常处理具有不同堆栈的多个项目)。

PS:nodemon 是为数不多的与 vboxsf 一起工作的文件观察器之一(参见 https://github.com/remy/nodemon/issues/419)。

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

这是 Vagrant 文件。您需要做的就是安装 vagrant,将其复制到一个名为 Vagrantfile 的文件中并将其放入某个文件夹中。转到该文件夹​​,只需执行 vagrant up 而不是正常的 boot2docker up。

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

让 docker 作为开发工具工作是可能的。但它会受伤。我在这里记录了这个过程:

http://harmingcola.blogspot.com/2015/05/how-to-setup-docker-as-development-tool.html

我决定用迄今为止找到的最佳解决方案添加我自己的答案。如果我找到更好的选择,我会更新这个。

迄今为止的最佳解决方案

我发现在 OS X 上使用 Docker 设置高效开发环境的最佳解决方案是:Boot2Docker + Rsync.使用 rsync,Docker 容器中的构建时间与 运行 直接在 OSX 上构建的时间相当!此外,文件观察器代码不需要轮询(inotify有效,因为rsync使用普通文件夹),所以热重载几乎快速地。

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

自动安装

我已经将使用 Rsync 设置 Boot2Docker 的所有步骤打包到一个名为 docker-osx-dev. The code is a bit rough, but I've been successfully using it for several weeks to easily switch between 3 projects with 3 different tech stacks. Try it out, report bugs, and submit some PRs! Also, see my blog post, A productive development environment with Docker on OS X 的开源项目中以获取更多信息。

手动设置

  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 上创建您需要的基本文件夹,并为它们正确设置权限。例如,如果您要从 OS X 同步 /foo/bar 文件夹,则需要在 Boot2Docker VM 上创建 /foo/barboot2docker ssh "mkdir -p /foo/bar && chown -R docker /foo/bar".
  6. 运行 rsync 将文件同步到 Boot2Docker 虚拟机:rsync --archive --rsh="ssh -i $HOME/.ssh/id_boot2docker -o StrictHostKeyChecking=no" /foo/bar docker@dockerhost:/foo。检查 rsync 文档以了解您可能想要启用的各种设置,例如在同步时使用 --exclude .git 排除 .git 文件夹。
  7. 使用文件观察器保持文件同步。例如,您可以使用通过管道传输到 rsync 的 fswatch (brew install fswatch)。
  8. 此时,您应该能够使用 docker run 来启动您的 Docker 容器并使用 -v 标志来装载您正在同步的文件夹:docker run -v /foo/bar:/src some-docker-image.
  9. 照常更新 OS X 上的代码。更改应该使用 rsync 非常快速地传播,普通文件观察程序代码应该像往常一样获取更改(即,使用 inotify),并且构建应该 运行 快,因为所有文件都是 "local" 到容器。
  10. 如果您需要测试 运行ning 网站,运行 boot2docker ip 命令可以查明它的 IP 地址。

此方法是在 Mac 上进行 Docker 设置的最新(2015 年 9 月)和最简单的方法: link here:

您安装 Docker 使用 Docker 工具箱 link to instructions here:

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

Docker Machine for 运行 docker-machine binary

Docker 运行 docker 二进制

的引擎

Docker 为 运行 编写 docker-compose 二进制文件

Kitematic,Docker GUI 为 Docker 命令行环境

预配置的 shell

Oracle VM VirtualBox

工具箱中有什么:

  • Docker 客户
  • Docker Mac海因
  • Docker 撰写(仅限 Mac)
  • Docker风筝
  • 虚拟盒子

我也在使用 Vagrant with 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

Docker Unison 很有魅力! https://github.com/leighmcculloch/docker-unison

双向同步,性能非常好!

Docker 对于 Mac 和 Windows 应该是开发的最终方式Docker OS X(和 Windows)。作为 Docker 产品,该软件是一个“集成的、易于部署的环境,用于从 Mac 或 Windows 构建、组装和运输应用程序。”它声称能够解决 OP 提出的问题。从它的 March 24, 2016 announcement:

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

免责声明:我可能有偏见,因为我是 docker-sync.

的作者

我可能尝试了这里提到的所有解决方案,包括更多(参见比较 https://github.com/EugenMayer/docker-sync/wiki/Alternatives-to-docker-sync),但它们基本上要么在性能方面(大部分)失败,要么在 docker-机器(或none)使用/强制执行。

http://docker-sync.io 已构建以合并所有解决方案并提供最佳策略(实施多个,您可以选择)。

它可以与 rsync(1 路同步)一起使用,包括用户权限修复,也可以与 unison(2 路同步)一起使用。它既不会强迫您进入 docker 机器或特定的管理程序,也不要求您为 Mac 设置 docker。它适用于所有这些。

性能EugenMayer/docker-sync/wiki/4.-性能不受影响,就像你没有股份一样。

docker-sync 及其更改观察器经过优化,可以毫无问题地处理具有 12k 文件的项目。

试一试,如果你喜欢,我很乐意听到反馈!