ReproNim / neurodocker

Generate custom Docker and Singularity images, and minimize existing containers
https://www.repronim.org/neurodocker/
Apache License 2.0
331 stars 97 forks source link

Error: Cannot assign requested address - with jupyter notebook #82

Closed miykael closed 7 years ago

miykael commented 7 years ago

Hi,

I'm not sure if it is a bug or if I'm doing something wrong. But I have an issue with using jupyter notebook within a neurodocker image. If I run jupyter notebook I get the following error:

neuro@9f1ad00fd1b6:~$ jupyter notebook
[W 09:05:04.084 NotebookApp] server_extensions is deprecated, use nbserver_extensions
Traceback (most recent call last):
  File "/opt/conda/envs/neuro/bin/jupyter-notebook", line 11, in <module> sys.exit(main())
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/jupyter_core/application.py", line 267, in launch_instance return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs)
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traitlets/config/application.py", line 657, in launch_instance app.initialize(argv)
  File "<decorator-gen-7>", line 2, in initialize
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/traitlets/config/application.py", line 87, in catch_config_error return method(app, *args, **kwargs)
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/notebook/notebookapp.py", line 1366, in initialize self.init_webapp()
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/notebook/notebookapp.py", line 1188, in init_webapp self.http_server.listen(port, self.ip)
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/tornado/tcpserver.py", line 142, in listen sockets = bind_sockets(port, address=address)
  File "/opt/conda/envs/neuro/lib/python3.6/site-packages/tornado/netutil.py", line 197, in bind_sockets sock.bind(sockaddr)
OSError: [Errno 99] Cannot assign requested address

But if I start jupyter notebook with jupyter notebook --ip 127.0.0.1 it works. In the same way, if I start the docker image with docker run -it --rm -p 8888:8888 my_docker_image jupyter notebook--ip 127.0.0.1 it works also.

I used the following docker command to create my neurodocker image:

docker run --rm kaczmarj/neurodocker generate -b neurodebian:stretch-non-free -p apt \
    --instruction "RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -" \
    --install dcm2niix convert3d ants graphviz tree git-annex-standalone vim emacs-nox nano less ncdu tig git-annex-remote-rclone xvfb mesa-utils build-essential nodejs \
    --afni version=latest \
    --fsl version=5.0.10 \
    --freesurfer version=6.0.0 min=True \
    --spm version=12 matlab_version=R2017a \
    --install psmisc libapparmor1 sudo \
    --instruction "RUN bash -c \"curl http://download2.rstudio.org/rstudio-server-\$(curl https://s3.amazonaws.com/rstudio-server/current.ver)-amd64.deb >> rstudio-server-amd64.deb && dpkg -i rstudio-server-amd64.deb && rm rstudio-server-amd64.deb\" " \
    --instruction "RUN curl -sSL https://dl.dropbox.com/s/lfuppfhuhi1li9t/cifti-data.tgz?dl=0 | tar zx -C / " \
    --user=neuro \
    --miniconda python_version=3.6 \
                conda_install="jupyter jupyterlab traits pandas matplotlib scikit-learn seaborn swig reprozip reprounzip altair traitsui apptools configobj vtk jupyter_contrib_nbextensions bokeh scikit-image" \
                env_name="neuro" \
                pip_install="https://github.com/nipy/nibabel/archive/master.zip https://github.com/nipy/nipype/tarball/master nilearn https://github.com/INCF/pybids/archive/master.zip datalad dipy nipy duecredit pymvpa2 mayavi git+https://github.com/jupyterhub/nbrsessionproxy.git" \
    --instruction "RUN bash -c \"source activate neuro && python -m ipykernel install --user --name neuro --display-name Py3-neuro \" " \
    --instruction "RUN bash -c \"source activate neuro && pip install --pre --upgrade ipywidgets pythreejs \" " \
    --instruction "RUN bash -c \"source activate neuro && pip install  --upgrade https://github.com/maartenbreddels/ipyvolume/archive/23eb91685dfcf200ee82f89ab6f7294f9214db8c.zip && jupyter nbextension install --py --sys-prefix ipyvolume && jupyter nbextension enable --py --sys-prefix ipyvolume \" " \
    --instruction "RUN bash -c \"source activate neuro && jupyter nbextension enable rubberband/main && jupyter nbextension enable exercise2/main && jupyter nbextension enable spellchecker/main \" " \
    --instruction "RUN bash -c \"source activate neuro && jupyter serverextension enable --sys-prefix --py nbrsessionproxy && jupyter nbextension install --sys-prefix --py nbrsessionproxy && jupyter nbextension enable --sys-prefix --py nbrsessionproxy \" " \
    --miniconda python_version=2.7 \
                env_name="afni27" \
                conda_install="ipykernel" \
                add_to_path=False \
    --instruction "RUN bash -c \"source activate afni27 && python -m ipykernel install --user --name afni27 --display-name Py2-afni \" " \
    --instruction "RUN bash -c \"source activate neuro && python -c 'from nilearn import datasets; haxby_dataset = datasets.fetch_haxby()' \" " \
    --workdir /home/neuro \
    --no-check-urls > Dockerfile

Now, one workaround to this issue is to create the file ~/.jupyter/jupyter_notebook_config.py with the content c.NotebookApp.ip = '*'. Therefore, I could just add the following command to my docker command:

--instruction "RUN bash -c \"echo c.NotebookApp.ip = '*' > ~/.jupyter/jupyter_notebook_config.py\" "

But is there a more straight forward way to handle this issue?

Thanks, Michael

kaczmarj commented 7 years ago

Hi @miykael - thanks for the report. What OS are you running? I have run into this issue on macOS. Jupyter notebook's default IP address is 'localhost' (under item NotebookApp.ip in the link). Apparently, using localhost makes the notebook available only inside the vm that docker for mac runs in (relevant stackoverflow answer and related discussion in the docker forums). You have at least three options for ip address: 127.0.0.1, 0.0.0.0, or . The jupyter notebook dockerfile sets the default ip address to 0.0.0.0, and [tensorflow sets it to ``](https://github.com/tensorflow/tensorflow/blob/738e4ddd0043c204095767f1f7458db9e6948262/tensorflow/tools/docker/jupyter_notebook_config.py#L18).

I would recommend not using * and instead using 127.0.0.1 or 0.0.0.0. You can include that --instruction to set the default IP address, or you can always call jupyter notebook with the --ip flag. Unfortunately, I do not know of a better way around this.

If you want to make jupyter notebook the entrypoint of the image, I would do this:

--entrypoint "jupyter notebook --ip=0.0.0.0 --no-browser"

which creates this layer:

ENTRYPOINT ["jupyter", "notebook", "--ip=0.0.0.0", "--no-browser"]
miykael commented 7 years ago

Hi @kaczmarj - thanks for your fast answer. My OS is Ubuntu 16.04.3 LTS (xenial).

I decided to use

--instruction "RUN bash -c \"echo c.NotebookApp.ip = \'0.0.0.0\' > /.jupyter/jupyter_notebook_config.py\" "

I've tried the to use

--entrypoint "jupyter notebook --ip=0.0.0.0 --no-browser"

but this approach seems to block me from any other use than notebooks. For example, if I try to open the docker image with

docker run -it --rm -p 8888:8888 my_docker_image:latest bash

I get the error that it cannot find bash.

Thanks again for the fast answer. In my opinion the issue can otherwise be closed.

cheers, Michael

kaczmarj commented 7 years ago

@miykael - sorry that most of what I wrote above was for Docker for Mac. I will investigate this more on Ubuntu Xenial before closing.

And if jupyter notebook is the entrypoint, you can enter a bash shell with

docker run -it --rm -p 8888:8888 --entrypoint=bash my_docker_image:latest

although this is a little cumbersome. I think your choice of setting the default ip address is the best option.

kaczmarj commented 7 years ago

hmm I've been digging a little bit, and the following command works on Ubuntu 16.04.3:

$ docker run --rm -it -p 8888:8888 --net=host my_docker_image
(container)$ jupyter notebook

but --net=host is not a good way to go because it might introduce security issues (the network is not containerized) and it is not reproducible (doesn't have the same effect in Docker for Mac).

I'll close the issue now.

miykael commented 7 years ago

Thanks for the further investigation!