Shubham Chaudhary
Shubham Chaudhary

Reputation: 51093

tornado/graphlab Cannot assign requested address in docker

Running gl.canvas.set_target('ipynb') throws following exeption in docker container.

Even with gl.canvas.set_target('ipynb', port=28892) where 28892 is an open port, the error stays the same.

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-257-3f215a521352> in <module>()
----> 1 gl.canvas.set_target('ipynb')

/opt/conda/envs/gl-env/lib/python2.7/site-packages/graphlab/canvas/utils.pyc in set_target(target, port)
    102             # and to preserve backwards compatibility/other use cases
    103             # (running a notebook exported to .py, for instance)
--> 104         _active_target = targets[target]()
    105 
    106     # track metrics on target

/opt/conda/envs/gl-env/lib/python2.7/site-packages/graphlab/canvas/target.pyc in __init__(self, port)
     25         self.state = graphlab.canvas.state.State()
     26         # TODO server is not necessary in static IPython/Jupyter Notebook
---> 27         self.server = graphlab.canvas.server.Server(self.state, port)
     28         # add data objects to left nav
     29         DataView = graphlab.canvas.views.data_objects.DataObjectsView()

/opt/conda/envs/gl-env/lib/python2.7/site-packages/graphlab/canvas/server.pyc in __init__(self, state, port)
     44 
     45         #Will raise exception if port cannot be bound
---> 46         self.__bind_socket(port)
     47 
     48     # methods

/opt/conda/envs/gl-env/lib/python2.7/site-packages/graphlab/canvas/server.pyc in __bind_socket(self, port)
     93     # Raises exception if socket cannot be bound on requested port
     94     def __bind_socket(self, port=None):
---> 95         sockets = tornado.netutil.bind_sockets(port,"localhost")
     96         self.__server.add_sockets(sockets)
     97         with self.__port_lock:

/opt/conda/envs/gl-env/lib/python2.7/site-packages/tornado/netutil.pyc in bind_sockets(port, address, family, backlog, flags, reuse_port)
    194 
    195         sock.setblocking(0)
--> 196         sock.bind(sockaddr)
    197         bound_port = sock.getsockname()[1]
    198         sock.listen(backlog)

/opt/conda/envs/gl-env/lib/python2.7/socket.pyc in meth(name, self, *args)
    226 
    227 def meth(name,self,*args):
--> 228     return getattr(self._sock,name)(*args)
    229 
    230 for _m in _socketmethods:

error: [Errno 99] Cannot assign requested address

It looks like more of a docker/tornado problem than graphlab issue, because in host machine the same command works.

I started my docker container using following command:

sudo docker run -it -v /path/to/data:/root/data \
    -v ~/code/work/src:/root/src \
    -p 8888:8888 -p 28892:28892 company/graphlab \
    /bin/bash -c "source activate gl-env && jupyter notebook --notebook-dir=~/src --ip='*' --port=8888 --no-browser"

Is there a way to figure out this port so that I can open it or any other way to fix this issue?

Upvotes: 2

Views: 3253

Answers (2)

Gergely
Gergely

Reputation: 196

The other answer by ForcaeLuz is on the good path, but only treats the symptoms.

Seems like it was recently fixed in Tornado in this commit, where the comments are very useful to see (how Docker's default configuration gives rise to this, for example).

On some systems (most notably docker with default configurations), ipv6 is partially disabled: socket.has_ipv6 is true, we can create AF_INET6 sockets, and getaddrinfo("localhost", ..., AF_PASSIVE) resolves to ::1, but we get an error when binding.

It's not yet released (as of the time of this writing), but could get it installing tornado from its master branch, e.g. by running

pip install --upgrade git+https://github.com/tornadoweb/tornado.git@master#egg=tornado

(or similar), or waiting for (I think) version 6.1.0 that should include this change. Tried it with some other projects that use tornado underneath and running into issues when within Docker, and it was all good after this.

Upvotes: 0

ForcaeLuz
ForcaeLuz

Reputation: 121

Editing your /etc/hosts file (inside the container) to only contain 1 ip address value for localhost solves the issue for me. It only works if you edit it on the running container. Editing it when building the image does not solve the problem.

At start-up from the container my /etc/hosts have the lines:

127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback

I had to change those to:

127.0.0.1   localhost
::1 ip6-localhost ip6-loopback

Upvotes: 7

Related Questions