Serving IPython notebook on public domain

I’ve been involved in teaching basic programming in Python. There are several good tutorials and on-line courses (just to mention Python@CodeCademy), but I’ve recognised there is a need for some interactive workplace for the students. I’ve got an idea to setup IPython in public domain, as many of the students don’t have Python installed locally or miss certain dependencies…
The task of installing IPython and serving it in publicly seems very easy… But I’ve encountered numerous difficulties on the way, caused by different versions of IPython (ie. split into Jupyter in v4), Apache configuration and firewall setup, just to mention a few. Anyway, I’ve succeeded and I’ve decided to share my experiences here 🙂
First of all, I strongly recommend setting up separate user for serving IPython, as only this way your personal files will be safe 😉

  1. Install IPython notebook and prepare new user
  2. [bash]
    # install python-dev and build essentials
    sudo apt-get install build-essential python-dev

    # install ipython; v3 is recommended
    sudo pip install ipython[all]==3.2.1

    # create new user
    sudo adduser ipython

    # login as new user
    su ipython
    [/bash]

  3. Configure IPython notebook
  4. [bash]
    # create new profile
    ipython profile create nbsever

    # generate pass and checksum
    ipython -c "from IPython.lib import passwd; passwd()"
    # enter your password twice, save it and copy password hash
    ## Out[1]: ‘sha1:[your hashed password here]’

    # add to ~/.ipython/profile_nbserver/ipython_notebook_config.py after `c = get_config()`
    c.NotebookApp.ip = ‘localhost’
    c.NotebookApp.open_browser = False
    c.NotebookApp.port = 8889
    c.NotebookApp.base_url = ‘/ipython’
    c.NotebookApp.password = u’sha1:[your hashed password here]’
    c.NotebookApp.allow_origin=’*’

    # create some directory for notebook files ie. ~/Public/ipython
    mkdir -p ~/Public/ipython
    cd ~/Public/ipython

    # start notebook server
    ipython notebook –profile=nbserver
    [/bash]

  5. Configure Apache2
  6. [bash]
    # enable mods
    sudo a2enmod proxy proxy_http proxy_wstunnel
    sudo service apache2 restart

    # add ipython proxy config to your enabled site ie. /etc/apache2/sites-available/000-default.conf
    # IPython
    <Location "/ipython" >
    ProxyPass http://localhost:8889/ipython
    ProxyPassReverse http://localhost:8889/ipython
    </Location>

    <Location "/ipython/api/kernels/" >
    ProxyPass ws://localhost:8889/ipython/api/kernels/
    ProxyPassReverse ws://localhost:8889/ipython/api/kernels/
    </Location>
    #END

    # restart apache2
    sudo service apache2 restart
    [/bash]

Your public IPython will be accessible at http://yourdomain.com/ipython .
The longest time it took me to realise that c.NotebookApp.allow_origin='*' line is crucial in IPython notebook configuration, otherwise the kernel is loosing connection with an error ‘Connection failed‘ or ‘WebSocket error‘. Additionally, in one of the servers I’ve been trying, there is proxy setup that block some ports high ports, thus it was impossible to connect to WebSocket even with ApacheProxy setup…
If you want to read more especially about setting SSL-enabled notebook, have a look at jupyter documentation.

Apache2 reading from sshfs share

Today, I have encountered problems trying to read data from sshfs share in apache2. I was getting 403 Forbidden error. It turned out you need to enable other_user in sshfs, so other users than the one mounting the share can access the data, as apache2 is using www-data user.
[bash]
# uncomment last line of /etc/fuse.conf
# Allow non-root users to specify the allow_other or allow_root mount options.
user_allow_other

# enable other_user and read access by non-root
sudo chmod a+r /etc/fuse.conf

# remount
sudo umount DESTINATION
sshfs -o allow_other SHARE DESTINATION
[/bash]

Inspired by serverfault and unix.stackexchange.