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