Jupiter notebook behind Nginx on Ubuntu 20.04.3

Run Jupyter notebook behind Nginx, with SSL via Let’s Encrypt. Jupyter notebook process to be monitored by supervisord. Supervisord process to run as ‘jupyter’ user.

Referrences

c.f. https://medium.com/bit2byte/deploying-jupyter-in-ubuntu-with-nginx-and-supervisor-f847b545023

c.f. https://medium.com/@nicklas_bocksberger/setting-up-jupyter-notebook-on-a-server-with-nginx-as-proxy-d579d4075bb

c.f. https://stackoverflow.com/questions/19918177/starting-supervisord-as-root-or-not

What I did

Some configs are lacking above to run Jupyter Notebook and access remotely:

#~/.jupyter/jupyter_notebook_config.py

# Allow access from anywhere
c.NotebookApp.allow_origin = '*'

# Allow remote access
c.NotebookApp.allow_remote_access = True

# Do NOT allow root access
c.NotebookApp.allow_root = False

# Host / IP address to be bound
c.NotebookApp.ip = '0.0.0.0'

# Notebook directory
c.NotebookApp.notebook_dir = '/your/path/to/jupyter_notebooks/'

# Port number
c.NotebookApp.port = 8888

## The number of additional ports to try if the specified port is not available
#  (env: JUPYTER_PORT_RETRIES).
#  Default: 50
# c.NotebookApp.port_retries = 50
c.NotebookApp.port_retries = 50

Configure password

jupyter-console
In [1]: from notebook.auth import passwd

In [2]: passwd()
Enter password: 
Verify password:
Out[3]: 'argon2:$argon2id$v=19$m=10240,t=10,p=8$zHFb+tE0xQO3rzlZ816diA$Zin64GHsWm3rsMpN13pmCIEuEsP6T51+cSxBNpFAVQM'

Configure the hashed password to the config file (jupyter_notebook_config.py)

## Hashed password to use for web authentication.
#  
#                        To generate, type in a python/IPython shell:
#  
#                          from notebook.auth import passwd; passwd()
#  
#                        The string should be of the form type:salt:hashed-
#  password.
#  Default: ''
# c.NotebookApp.password = ''
c.NotebookApp.password = 'argon2:$argon2id$v=19$m=10240,t=10,p=8$zHFb+tE0xQO3rzlZ816diA$Zin64GHsWm3rsMpN13pmCIEuEsP6T51+cSxBNpFAVQM'

Nginx config:

server {
    server_name YOUR.JUPYTER.HOME;

    listen 80;
    listen [::]:80;
    location / {
        proxy_pass http://0.0.0.0:8888;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

Enable the config file for Nginx:

sudo ln -s /etc/nginx/sites-available/jupyter.conf /etc/nginx/sites-enabled/

sudo service nginx restart

Use supervisor to run Jupyter Notebook as daemon:

sudo apt install supervisor
sudo vim /etc/supervisor/conf.d/jupyter.conf

#jupyter.conf

# jupyter.conf
[program:jupyter]
  
directory=/home/YOUR-USER-NAME/jupyter_notebooks/
command=sudo jupyter notebook --allow-root --config=/home/ubuntu/.jupyter/jupyter_notebook_config.py
autostart=true
autorestart=true
stderr_logfile=/var/log/jupyter.err.log
stdout_logfile=/var/log/jupyter.out.log

Restart supervisor process

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl

Output should be something like this:

minami:~$ sudo supervisorctl reread
jupyter: available
minami:~$ sudo supervisorctl update
jupyter: added process group
minami:~$ sudo supervisorctl
jupyter RUNNING pid 2191948, uptime 0:00:07
supervisor>

Head your browser to http://your.jupyter.host/

Log in with the password you configured above.

Use certbot to enable SSL

certbot
...

Run Jupyter Notebook as jupyter user

Create user:

sudo adduser
# create new user 'jupyter'

# add jupyter to sudoer
sudo usermod -aG sudo jupyter

Prepare a directory for jupyter notebook

sudo mkdir -p /opt/jupyter/jupyter_notebooks
sudo chown -R jupyter:jupyter /opt/jupyter

Copy jupyter config to jupyter user

sudo mkdir /home/jupyter/.jupyter
sudo cp ~/.jupyter/* /home/jupyter/.jupyter
sudo chown -R jupyter:juypter /home/jupyter/.jpuyter

Change supervisor config

#/etc/supervisor/conf.d/jupyter.conf

[program:jupyter]

# Change notebook directory   
directory=/opt/jupyter/jupyter_notebooks/
# Run jupyter as jupyter user
command=sudo -u jupyter jupyter notebook --config=/home/jupyter/.jupyter/jupyter_notebook_config.py
# Specify user
user=jupyter
autostart=true
autorestart=true
stderr_logfile=/var/log/jupyter.err.log
stdout_logfile=/var/log/jupyter.out.log

Reset supervisord

sudo supervisorctl reread
sudo supervisorctl update

Now jupyter notebooks should be saved in /opt/jupyter/jupyter_notebooks