Skip to content

Instantly share code, notes, and snippets.

@algal
Last active October 29, 2017 19:39
Show Gist options
  • Save algal/b6be7f4387886d4ef6a41f7f42474b5d to your computer and use it in GitHub Desktop.
Save algal/b6be7f4387886d4ef6a41f7f42474b5d to your computer and use it in GitHub Desktop.

Setting up a Jupyter server

These notes describe how to install and configure a secured Jupyter server directly onto Ubuntu 16.04.

Warning: this might be stupid. In 2017, it might be wiser just to grab a docker image, since some of these look extremely well-packaged. In my view, the advantage of docker is that someone else does the packaging, while docker itself provides cross-platform portability, rudimentary process supervision, and perhaps a simpler model than your OS's package manager. It is easy to know what is installed, how to uninstall it, and where its boundaries are. The disadvantage of docker is that you need to understand docker possibly in addition to understanding some Unix fundamentals.

Setup LetsEncrypt certs if needed

Install LetsEncrypt

$ sudo apt update
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo aptn update
$ sudo apt install certbot 

Create a cert

First, make sure you have either port 80 or port 443 open.

Check your firewall and your EC2 security-group, and make sure no other service is already bound to the port and listening on it.

$ # if you have port 80 open
$ sudo certbot certonly --standalone --preferred-challenges http -d example.com -d www.example.com
$ # alternatively, if you have port 443 open
$ sudo certbot certonly --standalone --preferred-challenges tls-sni -d example.com -d www.example.com

This will deposit a symlinks to a certificate file fullchain.pem and a private key privkey.pem in the directory /etc/letsencrypt/live/example.com/fullchain.pem.

(This simplifies these Lets Encrypt instructions.)

Install Jupyter

Install it:

$ pip install jupyter

Configure it to require a password

Interactively enter your password.

$ jupyter notebook password          # to set the notebook password interactively

If you do not set a password as above, the server will auto-generate a password token, which will show on the console. This is also fine.

Set it to serve via HTTPS to anyone, via a config file

$ jupyter notebook --generate-config # generates a config file with default configs

Now we modify the config file to serve openly. The file is at ~/.jupyter/jupyter_notebook_config.py.

You need to take care to point the jupyter config file at the physical file on disk, not the symlink, for fullchain.pem and privkey.pem. (I'm not sure how to square this with Let's Encrypt's auto-renewal mechanism, so I'm just pointing out the numbered file here, which will presumably expire and be replaced with the next number eventually.)

c.NotebookApp.certfile = u'/etc/letsencrypt/archive/alexisml.topology-engineering.com/fullchain1.pem' # configure certs
c.NotebookApp.keyfile = u'/etc/letsencrypt/archive/alexisml.topology-engineering.com/privkey1.pem'
c.NotebookApp.ip = '*'                             # let clients find us by any name not just localhost
c.NotebookApp.open_browser = False                 # do not open the browser
c.NotebookApp.port = 8888                          # listen on this port

(This simplifies these Jupyter instructions.)

Make it a startup service by using runit

Install runit (which has a slight learning curve but is the best:

$ sudo apt install runit
$ sudo mkdir /etc/sv/jupyter-daemon
$ sudo touch /etc/sv/jupyter-daemon/run
$ sudo chmod 0755 /etc/sv/jupyter-daemon/run

Create a run script /etc/sv/jupyter-daemon/run, which just calls the wrapper script:

#!/bin/sh
exec 2>&1
cd /home/ubuntu
exec chpst -uubuntu jupyter notebook

Alternative Jupyter configurations:

Set it to serve via HTTPS to anyone, via a shell script

Alternatively, instead of modifying the python config file, you can just create shell script run-jupyter.sh which passes in all the parameters, and always invoke via that. The advantage of this is you already know how to read and manage a shell script.

#!/bin/sh 
exec jupyter notebook \
    --certfile=/etc/letsencrypt/archive/alexisml.topology-engineering.com/fullchain1.pem \
    --keyfile=/etc/letsencrypt/archive/alexisml.topology-engineering.com/privkey1.pem \
    --ip='*' \
    --port=8888 \
    --no-browser

Make it a startup service by using systemd

Create a file /etc/systemd/system/jupyter.service:

[Unit]
Description=Jupyter service

[Service]
ExecStart=/usr/local/bin/jupyter notebook
WorkingDirectory=/home/ubuntu
User=ubuntu
Group=ubuntu

[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment