Docker port expose fails in Mac OS X

First off I went through tutorial and started flask app from tutorial in container. It did worked.

seraf$ docker run -d -P training/webapp python app.py

Then I found my virtual machine’s ip with

seraf$ boot2docker ip
192.168.59.103

And could access example app on http://192.168.59.103:49157:

Here is tutorial’s image Dockerfile:

FROM ubuntu:12.04
MAINTAINER Docker Education Team <[email protected]>
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl python-all python-pip wget
ADD ./webapp /opt/webapp/
WORKDIR /opt/webapp
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]

Now I’m trying to run my own flask app inside docker container. I’m building an image:

FROM ubuntu:12.04
MAINTAINER Serafim Suhenky <[email protected]>
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y python-dev
RUN apt-get install -y python-pip
RUN pip install gunicorn
RUN pip install flask
#VOLUME /web
ADD ./casa-web /web
WORKDIR /web
EXPOSE 5000
ENTRYPOINT python casa-web.py

Then I’m making a container:

docker run -d -P seraf1m/web-app

Or with more simple image:

docker run -d -P seraf1m/web-app python casa-web.py

Or this:

docker run -d -p 5000:5000 seraf1m/web-app python casa-web.py

And everything goes well so far; container started, port exposed and I can see app's logs.

But I can’t access my app via http://192.168.59.103:49158 or other ports that docker ps shows me.

At the same time I could access tutorial app.

What could be wrong with my image? Maybe something with the virtual machine?

seraf$ docker -v
Docker version 1.5.0, build a8a31ef

I also tried this fix; don’t know how it works:

#!/bin/bash
for i in {49000..49900}; do
 VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i";
 VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i";
done

Switched off virtual machine before running it. Then switch on and nothing changed. I rolled it back.


Solution 1:

That was a stupid mistake. Everything worked well with docker.

The problem was with Flask app, it is listening only for localhost by default. To make it listen to the network you need to set

app.run(host= '0.0.0.0')

So here is how it all works:

  1. Boot2docker installs virtual machine to you mac. You could ssh into it with boot2docker ssh.
  2. That virtual machine is like a gateway to running containers. Each container is a virtual pc behind that gateway. If you ssh'ed to the vm, you could ping containers. To find out container's ip you should attach to it

docker exec -it bash

Now you're inside container. You could run ifconfig or ip addr show to see you container's ip.

  1. Once you have container's ip you can ping it from vm. And try to connect to the exposed port. ( if you see 0.0.0.0:49155->5000/tcp in docker ps then to 5000)

curl container_ip:container_port

For me it refused to connect, however i could connect from container itself via curl localhost:5000

Thats how i figured it out.