Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward Ports from boot2docker using the Vagrant Docker provider

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

like image 928
Todd Avatar asked May 30 '14 06:05

Todd


2 Answers

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.

like image 164
Todd Avatar answered Oct 19 '22 13:10

Todd


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"
like image 25
Motin Avatar answered Oct 19 '22 13:10

Motin