Introduction
JupyterLab provides a web-based development environment for data science and AI projects. It is a flexible interface that allows developers to configure and manage machine learning and scientific computing workflows. JupyterLab is the next generation of the Jupyter Notebook. It's designed to fix many usability issues of the Notebook, and it greatly expands its scope with support for more than 40 programming languages, including R, Python, Scala, and Julia.
This article demonstrates the steps to configure and daemonize the JupyterLab server, set up the Nginx web server as a reverse proxy, and secure the environment using a Let's Encrypt SSL certificate.
Prerequisites
Before you begin, you should:
Deploy a Ubuntu 22.04 server.
Create a non-root sudo user.
Point a subdomain to your server using an
A
record. This article uses jupyterlab.example.com for demonstration.
Install the Required Packages
JupyterLab is an all-inclusive package; there are no extra packages you need to install manually other than the virtualenv
package, which is used to isolate the Jupyter kernel.
Install the virtualenv
package using pip
.
$ sudo pip install -U virtualenv
Create and activate a new Python virtual environment.
$ virtualenv --system-site-packages -p python3 jupyterlab_env
$ source jupyterlab_env/bin/activate
The above commands create a new directory on the server named jupyterlab_env
that contains the Python virtual environment files. You use the activate
binary file inside the bin
directory to enter the virtual environment.
Update the pip
package manager and deactivate the virtual environment.
(jupyterlab_env) $ pip install --upgrade pip
(jupyterlab_env) $ deactivate
Install the JupyterLab package.
$ sudo pip install -U jupyterlab
The above command installs the latest version of JupyterLab globally.
Configure the JupyterLab Server
By default, whenever you spawn a JupyterLab server, it generates a unique token that grants access to the interface. This section demonstrates the steps to configure the JupyterLab server to use a static password and allow remote access.
Generate a password hash.
$ python3 -c "from jupyter_server.auth import passwd; print(passwd('YOUR_PASSWORD'))"
The above command generates a hash of the provided input. It uses the Argon2 password hashing function to generate the hash.
Create a JupyterLab configuration file.
$ jupyter lab --generate-config
The above command generates a configuration file for persistent settings. It stores the configuration file in .jupyter
directory inside the user's home directory.
Edit the configuration file.
$ nano ~/.jupyter/jupyter_lab_config.py
Find and replace the following values in the file.
c.ServerApp.password = 'PASSWORD_HASH'
c.ServerApp.allow_remote_access = True
The above configuration allows JupyterLab to accept remote connections and sets a static password for interacting with the interface.
Disable the firewall.
$ sudo ufw disable
The above command disables the firewall allowing inbound connections to all the ports. You enable the firewall in the later steps to secure your server.
Run the JupyterLab server.
$ jupyter lab --ip 0.0.0.0
The above command spawns a JupyterLab server on the default port 8888
. You can open the interface in your web browser using http://PUBLIC_IP:8888
and log in using the password used in the previous steps. After confirming the access, stop the server using CTRL+C to follow along with the next steps.
Isolate the Jupyter Kernel
Jupyter notebooks use the Jupyter kernel to execute the code blocks. To keep the environment isolated to reduce conflicts, you isolate the kernel using the virtual environment created in the previous steps.
Uninstall the existing Jupyter kernel.
$ sudo python3 -m pip uninstall ipykernel
The above command removes the Jupyter kernel from the global environment.
Enter the virtual environment
$ source jupyterlab_env/bin/activate
Create a new Jupyter kernel.
(jupyterlab_env) $ pip install ipykernel
(jupyterlab_env) $ python3 -m ipykernel install --user --name=venvpy3
The above command installs the Jupyter kernel in the virtual environment. You can set the kernel's name using the --name
flag.
Copy $PATH
value into the clipboard.
(jupyterlab_env) $ echo $PATH
The above command outputs the value of the $PATH
variable. Copy the output or note it, as you will need this later to daemonize the JupyterLab server. If you do not set $PATH
variable, you will not be able to use the kernel properly.
Exit the virtual environment.
(jupyterlab_env) $ deactivate
Daemonize the JupyterLab Server
In this section, you create a new service for the JupyterLab server to run in the background and start automatically during the server boot process.
Create a new service named jupyterlab
.
$ sudo nano /lib/systemd/system/jupyterlab.service
Add the following contents to the file.
[Unit]
Description=JupyterLab Server
[Service]
User=USER
Group=USER
WorkingDirectory=/home/USER/jupyterlab
Environment="PATH=VIRTUAL_ENV_PATH_HERE"
ExecStart=/usr/local/bin/jupyter-lab --config=/home/USER/.jupyter/jupyter_lab_config.py
[Install]
WantedBy=multi-user.target
The above systemd
file content creates a new service named jupyterlab
, uses the generated configuration file to spawn the server, and sets the working directory to ~/jupyterlab
. Ensure that you replace the USER
and the PATH
values in the content.
Create the working directory for JupyterLab.
$ mkdir ~/jupyterlab
Initialize the jupyterlab
service.
$ sudo systemctl daemon-reload
$ sudo systemctl start jupyterlab
$ sudo systemctl status jupyterlab
You can confirm the access by opening the interface in your web browser using http://SERVER_IP:8888
and logging into it using the password used in the previous steps.
Set Up the Reverse Proxy Server
This section demonstrates the steps to install and configure the Nginx web server as a reverse proxy server that channels incoming HTTP/HTTPS traffic to the JupyterLab server.
Install the Nginx package.
$ sudo apt install nginx
Swap the Nginx configuration.
$ sudo rm -f /etc/nginx/nginx.conf
$ sudo nano /etc/nginx/nginx.conf
Add the following contents to the file.
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name jupyterlab.example.com;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Scheme $scheme;
proxy_buffering off;
}
location ~ /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
}
events {}
The above configuration channels all the incoming HTTP traffic on jupyterlab.example.com to localhost at port 8888
using a virtual host.
Restart the Nginx server.
$ sudo systemctl restart nginx
You can confirm the access by opening the interface in your web browser using http://jupyterlab.example.com
and log in to it using the password used in the previous steps.
Secure the Environment using Let's Encrypt
Let's Encrypt is an automated, open certificate authority that offers free TLS/SSL certificates for public benefit. It allocates the certificates using the ACME protocol. In this section, you will install the Certbot package, an ACME client that allows automatic SSL certificate issuance and renewals.
Install the Certbot package.
$ sudo snap install --classic certbot
Create a new Let's Encrypt certificate for the virtual host.
$ sudo certbot --nginx -d jupyterlab.example.com
The above command issues an SSL certificate and updates the Nginx configuration to use HTTPS. You can confirm the access by opening the interface in your web browser using https://jupyterlab.example.com
and log in to it using the password used in the previous steps.
Configure Firewall Rules
The JupyterLab environment requires inbound SSH, HTTP, and HTTPS traffic.
$ sudo ufw allow 'OpenSSH'
$ sudo ufw allow 'Nginx Full'
$ sudo ufw enable
$ sudo ufw status
Conclusion
This article demonstrated the steps to configure and daemonize the JupyterLab server, set up the Nginx web server as a reverse proxy, and secure the environment using a Let's Encrypt SSL certificate. Refer to the JupyterLab Documentation for more information.