Python - How to install jupyterhub on rocky linux
Install jupytherhub on a rocky linux server
As part of a course I have found the need / interest to setup a jupyterhub instance. This short post is an overview of the steps needed to achieve a running server.
First I install conda, jupyterhub and notebooks:
(base) [adrock2nd@pythoncourse ~]$ curl -O https://repo.anaconda.com/miniconda/Miniconda3-py39_4.12.0-Linux-x86_64.sh # download the installer from anaconda
(base) [adrock2nd@pythoncourse ~]$ chmod +x Miniconda3-py39_4.12.0-Linux-x86_64.sh # make the installer executable
(base) [adrock2nd@pythoncourse ~]$ ./Miniconda3-py39_4.12.0-Linux-x86_64.sh # this steps implies that you trust the installer
(base) [adrock2nd@pythoncourse ~]$ conda install jupyterhub # installs jupyterhub and proxy
(base) [adrock2nd@pythoncourse ~]$ conda install jupyterlab notebook # needed if running the notebook servers in the same environment
Test your installation:
(base) [adrock2nd@pythoncourse ~]$ jupyterhub -h
(base) [adrock2nd@pythoncourse ~]$ configurable-http-proxy -h
Generate a default configfile:
(base) [adrock2nd@pythoncourse ~]$ mkdir jupyterhub
(base) [adrock2nd@pythoncourse ~]$ jupyterhub --generate-config -f ~/jupyterhub/jupyterhub_config.py
Writing default config to: /home/adrock2nd/jupyterhub/jupyterhub_config.py
We want to encrypt the traffic to our service so we need a certificate. The easies way is probably to use letsencrypt:
(base) [adrock2nd@pythoncourse ~]$ sudo dnf install epel-release
(base) [adrock2nd@pythoncourse ~]$ sudo dnf upgrade
(base) [adrock2nd@pythoncourse ~]$ sudo yum install snapd
(base) [adrock2nd@pythoncourse ~]$ sudo systemctl enable --now snapd.socket
(base) [adrock2nd@pythoncourse ~]$ sudo ln -s /var/lib/snapd/snap /snap
(base) [adrock2nd@pythoncourse ~]$ sudo snap install core
(base) [adrock2nd@pythoncourse ~]$ sudo snap refresh core
(base) [adrock2nd@pythoncourse ~]$ sudo snap install --classic certbot
(base) [adrock2nd@pythoncourse ~]$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
(base) [adrock2nd@pythoncourse ~]$ sudo certbot certonly --standalone
(base) [adrock2nd@pythoncourse ~]$ sudo certbot renew --dry-run
...
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/pythoncourse.botnen.org/fullchain.pem
Key is saved at: /etc/letsencrypt/live/pythoncourse.botnen.org/privkey.pem
Edit your jupyterhub_config file with the following three changes:
c.JupyterHub.ssl_cert = '/etc/letsencrypt/live/pythoncourse.botnen.org/fullchain.pem'
c.JupyterHub.ssl_key = '/etc/letsencrypt/live/pythoncourse.botnen.org/privkey.pem'
c.JupyterHub.bind_url = 'https://:443'
Start your jupyterhub with elevated priviliges:
(base) [adrock2nd@pythoncourse ~]$ sudo /opt/miniconda3/bin/jupyterhub
You are now ready to login to the jupyterserver.
Basic security
We want to secure the server a little bit more than what it is as default. We will do a couple of things related to encrypting the traffic between the internal components of jupyterhub, mainly traffic between the 'proxy' and the 'notebook server' and traffic between the 'notebook server' and the 'kernel'. We also disable the possibility for our users to load their own configuration:
c.JupyterHub.internal_certs_location = 'internal-ssl'
c.JupyterHub.internal_ssl = True
c.JupyterHub.recreate_internal_certs = True
c.JupyterHub.trusted_alt_names = ['DNS:pythoncourse.botnen.org']
c.Spawner.disable_user_config = True
c.Spawner.args = ['--transport="IPC"']
c.Spawner.ssl_alt_names = ['DNS:pythoncourse.botnen.org']
Then we generate the certs and start the server:
(base) [adrock2nd@pythoncourse ~]$ sudo /opt/miniconda3/bin/jupyterhub
Create a shared folder for all our users
We want to provide coursematerial and examplefiles to all our users. We solve this by creating a shared folder that everyone has read/exec permissions to. Then we symlink the shared folder into every users homefolder. For this to work we need a textfile with all our usernames, one for each line.
(base) [adrock2nd@pythoncourse ~]# mkdir -p /srv/data/shared
(base) [adrock2nd@pythoncourse ~]# for i in `cat users.txt` ; do ln -sf /srv/data/shared /home/$i ; done
To be continued / Disclaimer
The above steps works, and will result in a jupyterhub, with encrypted traffic to and from the server. However there might be some steps that will make the setup more robus. I.e using a frontend webserver like apache or nginx instead of the build-in webserver, using a dedicated user / group to run the services instead of root +++. Use this steps as a start and then expand the setup to your needs before putting it into production.