Port forwarding in docker-machine?

Since boot2docker is deprecated I’ve switched to docker-machine but I don’t know how to open a port from docker-machine. In boot2docker I could do like this:

boot2docker ssh -L 27017:localhost:27017

This would forward port 27017 from VirtualBox to localhost 27017 as long as the SSH connection is open. Note that I’m not looking for a way to open the port permanently in VirtualBox. How can I achieve this with docker-machine?

  • Docker linked containers, Docker Networks, Compose Networks - how should we now 'link' containers
  • How to startup up services on a Docker image?
  • Confluence Error 500 while setup
  • Docker proper redirect link
  • How to make odoo read admin_passwd from file?
  • Logstash Removed from cluster after joining with elasticsearch in docker
  • docker - can't connect to external postgres db
  • Getting the latest version of Android SDK for Ubuntu using wget
  • Docker doesn't install correct on Mac
  • Use --build-arg value in Dockerfile FROM parameter
  • Docker number of lines in terminal changing inside docker
  • Docker with hypervisor
  • 6 Solutions collect form web for “Port forwarding in docker-machine?”

    You can still access the VBoxmanage.exe command from the VirtualBox used by docker machine:

    VBoxManage controlvm "boot2docker-vm" natpf1 "tcp-port27017,tcp,,27017,,27017";
    
    • Use docker-machine info to get the name of your vm.
    • use modifyvm if the vm isn’t started yet.

    See a practical example in this answer.


    That is the current workaround, pending the possibility to pass argument to docker-machine ssh: see issue 691.

    The other workaround is to not forward port, and use directly the IP of the VM:

     $(docker-machine ip default)
    

    With recent versions of machine, you can simply do (where default is the name of the machine):

    docker-machine ssh default -L 27017:localhost:27017
    

    This is a more temporary solution than the VM configuration change.

    Use the following variation to only forward ports in a background process:

    docker-machine ssh default -f -N -L 27017:localhost:27017
    
    • -f Requests ssh to go to background just before command execution.
    • -N Allow empty command (useful here to forward ports only)

    You can ssh into the machine and pass on the regular port forwarding arguments:

    ssh docker@$(docker-machine ip default) -L 27017:localhost:27017
    

    The password of the docker user is tcuser. (see https://github.com/boot2docker/boot2docker)

    Since I have hard time remembering how to do this I’ve created a small bash script called pf (which stands for “port forward”) that allows you to do:

    $ pf 8080
    

    This will forward the docker port 8080 to host port 8080 in the background (append -f to make it run in the foreground). To use a different host port just do:

    $ pf 8090:8080
    

    which maps the host port 8090 to 8080.

    To stop the port forwarding add -s:

    $ pf 8090:8080 -s
    

    (actually host port is enough as well: pf 8090 -s). There are other options available as well so checkout the github page.

    If you don’t want the need to use passwords, I would add that you should just point to the private key.

    ssh -L 8080:localhost:8080 -i ~/.docker/machine/machines/default/id_rsa docker@$(docker-machine ip default)
    

    Just to enhance in script the answer of @VonC – currently if using Docker Toolbox on MacOS X, the default VM machine is “default”. So a script to map all the exposed from container should look like:

    for port in `docker port cassandra | cut -d'-' -f1`; 
    do 
        port_num=`echo ${port} | cut -d'/' -f1`
        port_type=`echo ${port} | cut -d'/' -f2`
        echo "Create rule natpf1 for ${port_type} port ${port_num}"
        VBoxManage controlvm "default" natpf1 "${port_type}-port${port_num},${port_type},,${port_num},,${port_num}"
    done
    

    if you try to execute several times, a statement before creation should be added for deleting the existing rule:

    VBoxManage controlvm "default" natpf1 delete "${port_type}-port${port_num}"
    

    In the script it assumes that you have already port forward the ports from container to VM.

    docker port cassandra
    

    gives output like:

    7000/tcp -> 0.0.0.0:7000
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.