vagrant,docker,共享卷未在初始配置时准备就绪

时间:2015-06-08 16:00:09

标签: node.js macos docker vagrant virtualbox

我正在玩docker和vagrant以在os x上隔离我的开发环境。到目前为止一切顺利,我发现了一些很好的教程和介绍,但是一些帖子似乎已经过时了,因为流浪汉已经过时......

我的主要问题是将共享文件夹从我的主机安装到docker容器 - 它有点工作,但我不知道我是否遇到了vagrant / docker问题或者只是做错了什么。

让我解释一下我目前的状况:

我为我的虚拟机使用以下Vagrantfile.boot2docker并将当前目录挂载到vm中的/app。每当我更新主机上的文件时,我都能看到vm中的文件夹及其内容发生了变化。

VAGRANTFILE_API_VERSION = "2"
Vagrant.require_version ">= 1.6.3"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "yungsang/boot2docker"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.synced_folder ".", "/app", type: "rsync"
  # Uncomment below to use more than one instance at once
  # config.vm.network :forwarded_port, guest: 2375, host: 2375, auto_correct: true
  # Fix busybox/udhcpc issue
  config.vm.provision :shell do |s|
    s.inline = <<-EOT
      if ! grep -qs ^nameserver /etc/resolv.conf; then
        sudo /sbin/udhcpc
      fi
      cat /etc/resolv.conf
    EOT
  end
  # Adjust datetime after suspend and resume
  config.vm.provision :shell do |s|
    s.inline = <<-EOT
      sudo /usr/local/bin/ntpclient -s -h pool.ntp.org
      date
    EOT
  end
  config.vm.network :forwarded_port, guest: 5000, host: 5000
end

在我的Vagrantfile我创建两个单独的docker容器,一个隔离的redis实例和我的节点应用程序,它将app目录从vm安装到容器d.volumes=["/app:/foo"]

VAGRANTFILE_API_VERSION = "2"
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "redis" do |redis|
    redis.vm.provider 'docker' do |d|
      d.image  = 'redis:latest'
      #Comment the line below if you are running on a linux host
      d.vagrant_vagrantfile = "./Vagrantfile.boot2docker"
      d.name   = 'redis'
    end
  end
  config.vm.define "node_app" do |node_app|
      node_app.vm.provider "docker" do |d|
      d.name = 'node_app'
        d.build_dir = "."
        #Comment the line below if you are running on a linux host
        d.vagrant_vagrantfile = "./Vagrantfile.boot2docker"
        d.ports = ["5000:5000"]
        d.volumes = ["/app:/foo"]
        d.link('redis:redis')
      end
  end
end

我的Dockerfile加载最新的nodejs容器,并在安装依赖项和运行应用程序之前将package.jsonapp.js从主机复制到app目录。当前目录中的文件夹的静态副本运行良好,我的应用程序连接到redis并且工作我可以按预期在http://192.168.33.10:5000到达它! (注意:我已经在这里注释掉了VOLUME命令,所以文件只是在生命周期开始时被复制到容器中)

FROM node:latest
#use vagrant shared folder
ADD . /app

WORKDIR /app

# install your application's dependencies
RUN npm install
# exposes our app port
EXPOSE 5000
# replace this with your main "server" script file
CMD ["node", "app.js"]

在我第一次成功后,我尝试使用我的共享卷并更改了Dockerfile,如下所示:

FROM node:latest
#use vagrant shared folder
ADD . /foo
# mount volume
VOLUME ['/foo']
WORKDIR /foo

# install your application's dependencies
RUN npm install
# exposes our app port
EXPOSE 5000
# replace this with your main "server" script file
CMD ["node", "app.js"]

我重新加载了vm并遇到了一堆错误:主要是no package.json foundnpm module missing (express)。我已经想通了 - 通过使用第一个Dockerfile和以下node.js app https://gist.github.com/joernroeder/e86a3882360497c828f9(它只列出了/foo中的文件及其内容) - 该卷需要一些时间来挂载,用它自己的初始内容替换foo的内容,并删除生成的文件(包括node_modules目录)。 因此/foo内的文件反映了主机的变化,同步效果很好。

你有什么提示和技巧可以让我及时安装音量,还是我在这里完成一些完全愚蠢的事情?

由于

1 个答案:

答案 0 :(得分:1)

只有在执行dockerfile并启动容器后,node_app容器d.volumes = ["/app:/foo"]的已定义卷才可用。

解决方法是首先在dockerfile中使用Add /app /foo,在容器创建之后,静态添加的数据将被卷装载覆盖。

可以在此处找到docker和compose的示例实现:https://github.com/b00giZm/docker-compose-nodejs-examples/tree/master/02-express-redis-nodemon。请注意,这也可以在不使用vagrant和docker提供程序的情况下进行。