如何为多个提供者编写一个Vagrantfile,每个提供者使用不同的方框?

我的目标是创build一个Vagrantfile,我可以select使用Docker或VirtualBox使用–provider标志(例如vagrant up –provider = virtualbox)。 我遇到了一个问题,因为Docker提供者说我的盒子不兼容。 这是真的,但我不希望Docker使用这个盒子; 我有一个我指向Docker使用的Dockerfile。 我只想在VirtualBox是提供者的情况下使用这个盒子。 如何让Docker提供程序忽略框声明或仅在VirtualBox是提供程序时才使框声明运行?

这是我的stream浪文件:

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 

你只需要移动基于提供者的盒子条件

 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 

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

我的解决scheme是parsing传递的提供者参数,并将提供者声明包装在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