51

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?

6 Answers 6

48

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) 

As commented by sdc:

You can confirm that port forwarding is set up correctly with

 VBoxManage showvminfo boot2docker-vm | grep "NIC.* Rule" 
Sign up to request clarification or add additional context in comments.

5 Comments

While this works it's not really what I want to achieve. I would prefer if the settings weren't made permanent (I've updated the question to reflect this). If this doesn't work I'm still grateful for your answer.
@Johan I have edited the answer to explain why I proposed VM port forwarding, instead of ssh.
Great!! Thanks a lot.
You can confirm that port forwarding is set up correctly with VBoxManage showvminfo boot2docker-vm | grep "NIC.* Rule"
@sdc Thank you. I have included your comment in the answer for more visibility.
29

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)

4 Comments

trying to execute docker-machine ssh default -N -L 80:localhost:80 and have error: Privileged ports can only be forwarded by root. exit status 255
also if i try to sudo docker-machine ssh default -N -L 80:localhost:80 I have another notice machine does not exist
@noonehos as I say in my answer, default is a name of a machine. Find yours by typing docker-machine ls.
With Boot2Docker version 1.11.2 and docker-machine version 0.7.0, build a650a40 I got this error: sh: illegal option -L...
18

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)

2 Comments

Thanks, very helpful. By the way, on most systems this will only make the port 27017 bound to the local loopback adapter, meaning it can't be accessed from outside the host. Use ssh docker@$(docker-machine ip default) -L 1.2.3.4:27017:localhost:27017 to expose it to the outside world, where 1.2.3.4 is the local IP address.
Is it possible to forward multiple ports with docker-machine ssh? eg. -L 27017:localhost:27017 -L 3000:localhost:3000
10

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.

Comments

4

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) 

Comments

1

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 

1 Comment

NOTE: the script assumes that the running container name is "cassandra" - in the for loop. (docker port cassandra)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.