Docker on OSX: Port Forwarding

If you’ve tried to run Docker 0.8 on OSX, you know that everything works great except for port forwarding. Have no fear, here is your guide to getting port forwarding working for Docker on OSX:

Step 1. Export the port in your container

First, you should make sure to expose the port in the image you are running. If you are using a pre-built image this is usually taken care of for you, but if you are building an image yourself from a Dockerfile you need to add the following line near the end:

EXPOSE 80

The EXPOSE command exposes port 80 to the external of the container (If you need to expose a different port just use that instead of 80). Then, when launching the container based on this image be sure to specify the port binding you would like to use:

docker run -n -p 80:80 -d YOUR_IMAGE

The -p option tells docker to bind port 80 on the host (your laptop) to port 80 in the container (which we exposed in the image).

Normally, on pure linux systems, you would now be able to connect to the container on port 80. On OSX this isn’t the case.

Step 2. Configure VirtualBox 

Docker 0.8 for OSX relies on boot2docker which in turn uses VirtualBox to host the VM that runs the linux OS to run the containers. Unfortunately, despite the fact that you have told Docker to forward ports, VirtualBox doesn’t know about your port forwarding intentions and is blocking connections. You need to open up port forwarding in VirtualBox as well by running the following command:

VBoxManage modifyvm "boot2docker-vm" --natpf1 "guestnginx,tcp,,80,,80"

This uses the VirtualBox command line interface to update the boot2docker virtual machine to forward everything from port 80 on your laptop to port 80 in the virtual machine which will then, in turn, be available to your containers. –natpf1 specifies the first virtual network device of the VM handles the forwarding, but that is not an important detail.

Now you should be able to reach your container on port 80!

Conclusion

While this does work, it is very inconvenient if you run many containers using many different ports. It is a side effect of OSX not supporting containers natively, requiring another OS layer between you and your containers. Unfortunately boot2docker cannot take care of this for you since it doesn’t know what ports you need when you are getting started and once the Docker daemon is running in the virtual machine it cannot be modified.

Until there is a better solution, I recommend using a linux machine for most of your container testing and only using your OSX laptop for development testing.