如何为多个使用不同盒子的提供者编写Vagrant文​​件?

时间:2017-10-07 18:49:40

标签: docker vagrant virtualbox

我的目标是创建一个Vagrantfile,我可以选择使用--provider标志使用Docker或VirtualBox(例如vagrant up --provider = virtualbox)。我遇到了一个问题,因为Docker提供商说我的盒子不兼容。这是事实,但我不希望Docker使用这个盒子;我有一个Dockerfile,我指向Docker使用。我希望仅当VirtualBox是提供者时才使用该框。如何让Docker提供程序忽略box声明或仅在VirtualBox是提供者时才运行box声明?

这是我的Vagrantfile:

Vagrant.require_version ">= 1.7.0"

Vagrant.configure('2') do |config|
  PROJECT_ROOT = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..'))

  config.vm.provider "docker" do |d|
    d.build_dir = "."
    d.has_ssh = true
  end

  config.vm.box = "ubuntu/trusty64" # <--------- this is the line the Docker provider chokes on
  config.vm.provider "virtualbox" do |v|
    v.gui = true
  end

  config.vm.network :forwarded_port, guest: 80, host: 9002
  config.vm.network :forwarded_port, guest: 9000, host: 9000
  config.vm.network :forwarded_port, guest: 9001, host: 9001

  config.vm.synced_folder PROJECT_ROOT, '/srv'

  config.vm.provision :ansible do |ansible|
    ansible.verbose = "v"
    ansible.playbook = 'provisioning/playbook.yml'
  end
end

2 个答案:

答案 0 :(得分:1)

您只需根据提供商

移动该框条件
Vagrant.require_version ">= 1.7.0"

Vagrant.configure('2') do |config|
  PROJECT_ROOT = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..'))

  config.vm.provider "docker" do |d|
    d.build_dir = "."
    d.has_ssh = true
  end

  config.vm.provider "virtualbox" do |v, override|
    override.vm.box = "ubuntu/trusty64"
    v.gui = true
  end

  config.vm.network :forwarded_port, guest: 80, host: 9002
  config.vm.network :forwarded_port, guest: 9000, host: 9000
  config.vm.network :forwarded_port, guest: 9001, host: 9001

  config.vm.synced_folder PROJECT_ROOT, '/srv'

  config.vm.provision :ansible do |ansible|
    ansible.verbose = "v"
    ansible.playbook = 'provisioning/playbook.yml'
  end
end

答案 1 :(得分:0)

问题从根本上归结为这样一个事实,即Vagrant有一个内在的假设,即盒子和提供者是完全独立的,可以任意组合交换。这不是真的。一个框仅与其设计使用的提供程序兼容。正确的设计将允许每个提供者指定自己的盒子,而不是让盒子成为全局值。这种设计已经存在于Docker提供程序中,它允许您选择Docker镜像,但在任何其他提供程序中都不存在。就我而言,这是Vagrant中的一个错误。

我的解决方法是解析传递的provider参数并将提交声明包装在if语句中:

require 'optparse'

def get_provider
  ret = nil
  opt_parser = OptionParser.new do |opts|
    opts.on("--provider provider") do |provider|
      ret = provider
    end
  end
  opt_parser.parse!(ARGV)
  ret
end
provider = get_provider || "virtualbox"

PROJECT_ROOT = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..'))

Vagrant.require_version ">= 1.7.0"

Vagrant.configure('2') do |config|
  if provider == "docker"
    config.vm.provider "docker" do |d|
      d.build_dir = "."
      d.has_ssh = true
    end
  end

  if provider == "virtualbox"
    config.vm.box = "ubuntu/trusty64"
    config.vm.provider "virtualbox" do |v|
      v.gui = true
    end
  end

  config.vm.network :forwarded_port, guest: 80, host: 9002
  config.vm.network :forwarded_port, guest: 9000, host: 9000
  config.vm.network :forwarded_port, guest: 9001, host: 9001

  config.vm.synced_folder PROJECT_ROOT, '/srv'

  config.vm.provision :ansible do |ansible|
    ansible.verbose = "v"
    ansible.playbook = 'provisioning/playbook.yml'
  end
end
相关问题