Jupyterhub with SageMath Kernel
Recently I made some efforts to get a Jupyterhub instance with a SageMath kernel up and running on one of my servers β with success! π Actually, the installation is really not that difficult. Nevertheless, I want to write a few lines describing the troubles I ran into and my solutions.
Installing Dependencies
The dependencies of Jupyterhub are well-explained on their github page, and their installation should not result in big trouble. However, as my server runs CentOS 7.2, I had to compile a recent Python version by myself:
~ $ sudo yum groupinstall "Development tools"
~ $ sudo yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
~ $ wget http://python.org/ftp/python/3.5.1/Python-3.5.1.tar.xz
~ $ tar xf Python-3.5.1.tar.xz
~ $ cd Python-3.5.1
~/Python-3.5.1 $ ./configure --prefix=/usr/local --enable-shared
~/Python-3.5.1 $ make
~/Python-3.5.1 $ sudo make install
Then, in order to find the library, you have to add the line /usr/local/lib
to /etc/ld.so.conf.d/local.conf
and reload the config by calling ldconfig
.
These steps (usually) have to be completed as root. Afterwards,
Python 3.5.1 should
be installed (you can check with python3.5 -V
or pip3.5 -V
).
The goal of these steps was to obtain a useable installation of pip.
The installation of the second dependency, the node package manager βnpmβ was straightforward:
~ $ sudo yum install npm.noarch
~ $ sudo npm install -g configurable-http-proxy
Installation of Jupyterhub and linking the SageMath kernel
The next part is really easy: Jupyterhub (together with the notebook) can be installed with the help of pip just by calling
~ $ sudo pip install jupyterhub
~ $ sudo pip install notebook
The available kernels then can be listed with jupyter-kernelspec
:
~ $ jupyter-kernelspec list
Available kernels:
python3 /usr/local/lib/python3.5/site-packages/ipykernel/resources
In order to add a SageMath-kernel to your
installation, you first need a working Sage install. For example, Iβve
installed sage-6.10
in the /opt
-directory, so that I can run Sage by calling
~ $ /opt/sage-6.10/sage
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SageMath Version 6.10, Release Date: 2015-12-18 β
β Type "notebook()" for the browser-based notebook interface. β
β Type "help()" for help. β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
sage:
Then, all that needs to be done is linking the kernel into a directory, where Jupyter is aware of them:
~ $ sudo mkdir -p /usr/local/share/jupyter/kernels
~ $ cd /usr/local/share/jupyter/kernels
/usr/local/share/jupyter/kernels $ sudo ln -s /opt/sage-6.10/local/share/jupyter/kernels/sagemath
After linking the kernel, jupyter-kernelspec
list should already list the new kernel like this:
~ $ jupyter-kernelspec list
Available kernels:
python3 /usr/local/lib/python3.5/site-packages/ipykernel/resources
sagemath /usr/local/share/jupyter/kernels/sagemath
Note: Some versions of SageMath require editing the kernel.json
file
(which can be found in the folder /path/to/sage/local/share/jupyter/kernels/sagemath
)
such that the environment variable SAGE_ROOT
is set. In this example here, this means
adding the line
"env": { "SAGE_ROOT": "/opt/sage-6.10" },
to the kernel.json
file. This step is required if the error
Error: You must set the SAGE_ROOT environment variable or run this
script from the SAGE_ROOT or SAGE_ROOT/local/bin/ directory.
Error setting environment variables by sourcing β/opt/sage-6.10/local/bin/sage-envβ;
possibly contact sage-devel (see http://groups.google.com/group/sage-devel).
appears when trying to start the SageMath kernel. (Thanks to Clemens Heuberger for pointing this out!)
Configuring the Webserver
In my case, I configured Jupyterhub to run behind a reverse proxy, powered by
an Apache web server, such that the service can be reached from a subdomain
like https://jupyter.example.com
.
First, note that Jupyterhub can be started just by using the command jupyterhub
.
With jupyterhub --port 98765
, you can run the serivce at localhost:98765
.
The complicated part with the Apache configuration is that you also have to
take care of the websockets β otherwise the kernels are not able to connect.
The following snippet comes from my Apache configuration:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName jupyter.example.com
ProxyPass / http://localhost:98765/
ProxyPassReverse / http://localhost:98765/
Header edit Origin "jupyter.example.com" localhost:98765
RequestHeader edit Origin "jupyter.example.com" localhost:98765
Header edit Referer "jupyter.example.com" localhost:98765
RequestHeader edit Referer "jupyter.example.com" localhost:98765
<Location ~ "/(user/[^/]*)/(api/kernels/[^/]+/channels|terminals/websocket)/?">
ProxyPass ws://localhost:98765
ProxyPassReverse ws://localhost:98765
</Location>
# [... SSL Stuff etc ...]
</VirtualHost>
</IfModule>
And finally, in order to have Jupyterhub in a systemd-setting,
Iβve put the following into /usr/lib/systemd/system/jupyterhub.service
:
[Unit]
Description=Jupyterhub
[Service]
User=root
ExecStart=/usr/local/bin/jupyterhub --port 98765
[Install]
WantedBy=multi-user.target
β¦ and thatβs it! The service can then be started by reloading the
configuration via sudo systemctl daemon-reload
and
sudo systemctl start jupyterhub.service
.