Reputation: 23722
My goal is to create one Vagrantfile where I can choose to use either Docker or VirtualBox using the --provider flag (e.g. vagrant up --provider=virtualbox). I'm running into a problem because the Docker provider is saying that my box is not compatible. This is true but I don't want Docker to use this box; I have a Dockerfile which I point to for Docker to use. I want the box to be used only if VirtualBox is the provider. How can I make the Docker provider ignore the box declaration or make the box declaration run only when VirtualBox is the provider?
This is my 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
Upvotes: 1
Views: 1549
Reputation: 146510
You just need to move that box condition based on provider
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
Upvotes: 4
Reputation: 23722
The problem fundamentally comes down to the fact that Vagrant has a builtin assumption that boxes and providers are totally independent and can be swapped in any combination. This is not true. A box is compatible only with the providers it is designed to work with. The correct design would allow each provider to specify its own box instead of have the box be a global value. This design already exists in the Docker provider which allows you to choose a Docker image, but does not exist in any other provider. As far as I'm concerned this is a bug in Vagrant.
My solution to this is to parse the provider argument passed and wrap the provider declarations in if statements:
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
Upvotes: 1