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 support visual studio 2017 fails
  • HDFS as volume in cloudera quickstart docker
  • Deploying Java application in tomcat docker container
  • Can I run Docker directly on a non VT-X machine (no Virtual Machine used)? [closed]
  • docker-compose doesn't build image from latest commit of git repository
  • How to move Postresql to RAM disk in Docker?
  • How to start selenium hub and one linked node via docker-compose instead of using docker?
  • Building a compiled application with Docker
  • Passing arguments to docker swarm containers
  • How can i run rethinkdb-dump/export in RethinkDB + Docker
  • GCloud: Copying Files from Local Machine into a Docker Container
  • How to create a docker image for php and node?
  • 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.