How to run IPython behind an Apache proxy

Laryx Decidua picture Laryx Decidua · May 27, 2014 · Viewed 12.5k times · Source

I would like to run an IPython notebook web server behind an Apache (reverse) proxy so that instead of the URL

https://my.server:XXXX

(where XXXX is some port number) I could use

https://my.server/py0

I am aware that IPython uses websockets and I suspect this is the part that is missing from my setup, but I simply could not find a suitably detailed description on how to configure this. Unfortunately the IPython webserver setup docs don't have much to say regarding proxies apart from this:

When behind a proxy, especially if your system or browser is set to autodetect the proxy, the notebook web application might fail to connect to the server’s websockets[...]

So I decided to try it on my own and put the following in /etc/apache2/sites-enabled/default-ssl.conf :

            SSLProxyEngine On
            SSLProxyVerify none
            SSLProxyCheckPeerCN off
            SSLProxyCheckPeerName off
            ProxyPass       /py0/ https://localhost:10000/
            ProxyPassReverse        /py0/ https://localhost:10000/

Accessing IPython "directly" over the URL https://my.server:10000 works perfectly as advertised.

The URL https://my.server/py0 (without a trailing slash) returns "404 Not found".

The same with a trailing slash https://my.server/py0/ does "work" in that it forwards to https://my.server/login?next=%2F, which is then "Not found" in its own right -- obviously because the /py0/ part got lost. Maybe I should tell IPython about it but how ??

Perhaps relevant version numbers: Ubuntu 14.04 LTS, Apache 2.4.7.

Perhaps relevant SO question: IPython behind nginx. However, since everything else in my setup is handled by Apache to my full satisfaction, I do not want to run Nginx in addition.

Is there any good soul out there who has successfully configured IPython notebook web servers behind Apache? If yes, then please step forward and share your knowledge :-) Many thanks!

Answer

Adam picture Adam · Mar 2, 2015

I got this working using the following setup.

IPython

IPython Notebook is listening at http://localhost:8888/ipython. It was necessary to add the /ipython prefix, because IPython uses absolute paths, so it must be the same as the reverse proxied path.

The ipython_notebook_config.py

c = get_config()
c.NotebookApp.ip = 'localhost'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.base_url = '/ipython'

Apache

I enabled

  • mod_proxy
  • mod_proxy_http
  • mod_proxy_wstunnel

In the apache config I added

<Location /ipython>
ProxyPass        http://localhost:8888/ipython
ProxyPassReverse http://localhost:8888/ipython
ProxyPassReverseCookieDomain localhost my.server.com
RequestHeader set Origin "http://localhost:8888"
</Location>

<Location /ipython/api/kernels/>
ProxyPass        ws://localhost:8888/ipython/api/kernels/
ProxyPassReverse ws://localhost:8888/ipython/api/kernels/
</Location>

to an SSL enabled virtual host definition.

The RequestHeader set Origin "http://localhost:8888" was necessary for the websockets, otherwise you get a 403 Forbidden.

Now IPython is reachable at https://my.server.com/ipython (no trailing /!).