I'm trying to utilize Vagrant 1.6's Docker provider and I seem to have run into a snag. I can successfully bring up the Docker container and guest OS, but then I can't access the service I've brought up within the container from the host OS. Here's my Vagrantfile:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.network :forwarded_port, guest: 8000, host: 8000
config.vm.define "icecast" do |v|
v.vm.provider "docker" do |d|
d.image = "moul/icecast"
d.ports = ["8000:8000"]
d.env = {
# SOURCE_PASSWORD: 'password',
ADMIN_PASSWORD: 'password',
# PASSWORD: 'password',
# RELAY_PASSWORD: 'password'
}
end
end
end
My understanding is that running vagrant up --provider=docker
on OS X will start a VM running boot2docker that will then run my container. Running vagrant docker-logs
seems to confirm that my container is created and the service started, but now I can't for the life of me figure out how to access the service from my OS X host. If I was using a standard VirtualBox provider, I would expect the config.vm.network :forwarded_port
directive to handle the forwarding, but adding that doesn't seem to make any difference.
What do I need to do to be able to access this service from my OS X host?
Update: For reference, here is the image's Dockerfile: https://github.com/moul/docker-icecast/blob/master/Dockerfile
Ok, so I finally figured this out and it turns out the solution is to not use boot2docker at all. Based on some diving I did through the Vagrant source, reading issues, and rewatching the Docker provider introduction videos, it turns out that you need to use a proxy VM to host your containers instead of boot2docker.
To set this up, I modified my Vagrantfile to include a configuration option for vagrant_vagrantfile
:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define "icecast" do |v|
v.vm.provider "docker" do |d|
d.image = "moul/icecast"
d.ports = ["8000:8000"]
d.env = {
# SOURCE_PASSWORD: 'password',
ADMIN_PASSWORD: 'password',
# PASSWORD: 'password',
# RELAY_PASSWORD: 'password'
}
d.vagrant_vagrantfile = "./Vagrantfile.proxy"
end
end
end
Then I added an additional file (Vagrantfile.proxy) that Vagrant will use to spin up the proxy VM:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.provision "docker"
config.vm.provision "shell", inline:
"ps aux | grep 'sshd:' | awk '{print $2}' | xargs kill"
config.vm.network :forwarded_port, guest: 8000, host: 8000
end
Using the Docker provisioner will automatically install Docker on the proxy VM for you. The inline shell script forces Vagrant to log back into the box so that it can utilize Docker after it's been installed. Finally, I forward the port I need in this Vagrantfile as opposed to the original (while still using the ports
config option in the original).
Just like with the default boot2docker strategy, Vagrant will be smart enough to reuse existing instances of the proxy VM for any image that utilizes it.
Hopefully this will be helpful to someone down the road.
To forward Ports from boot2docker (as opposed to forwarding ports from a custom proxy VM that's not using boot2docker), you need to add port forwards manually through VirtualBox, or run the following script after running vagrant up
:
export PORT=3306
export REASON=mysql
export HOST_VM=`VBoxManage list runningvms | grep docker-host | awk '{ print $1 }' | sed 's/"//g'`
VBoxManage controlvm $HOST_VM natpf1 "docker-$REASON-$PORT-port-forward,tcp,127.0.0.1,$PORT,,$PORT"