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:
- Boot2docker installs virtual machine to you mac. You could ssh into it with
boot2docker ssh
. - 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.
- 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
indocker 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.