How to Set up a JupyterLab Environment on Ubuntu 22.04
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.console$ apt update $ apt install python3-virtualenv
Create a new directory and navigate into it.
console$ mkdir /home/USER/jupyter-env $ cd /home/USER/jupyter-env
Create and activate a new Python virtual environment.
console$ virtualenv env $ source env/bin/activate
The above commands create a new directory on the server named
env
that contains the Python virtual environment files. You use theactivate
binary file inside thebin
directory to enter the virtual environment.Update the
pip
package manager.console(env) $ pip install --upgrade pip
Install the JupyterLab package.
console(env) $ sudo pip install -U jupyterlab
The above command installs the latest version of JupyterLab.
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.
console(env) $ 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.
Copy the generated hash for later use.
Create a new directory to organize Jupyter Notebooks.
console(env) $ mkdir /home/USER/jupyter-env/notebooks
Create a JupyterLab configuration file.
console(env) $ sudo nano /home/USER/jupyter-env/config.py
The above command generates a configuration file for persistent settings.
Copy and paste the below configurations.
pythonfrom jupyter_server.auth.identity import PasswordIdentityProvider c.ServerApp.allow_remote_access = True c.ServerApp.allow_origin = '*' c.ServerApp.root_dir = "/home/USER/jupyter-env/notebooks" PasswordIdentityProvider.hashed_password = ''
The above configuration allows JupyterLab to accept remote connections and sets a static password for interacting with the interface.
Make sure to provide the hash generated earlier in the configuration.
Save and exit the file.
Disable the firewall.
console(env) $ 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.
console(env) $ jupyter lab --ip 0.0.0.0 --config config.py
The above command spawns a JupyterLab server on the default port
8888
. You can open the interface in your web browser usinghttp://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.
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.
Get the paths for Python and Jupyter.
console(env) $ which python (env) $ which jupyter
Copy the paths to use them in the
systemd
service.Deactivate the virtual environment.
console(env) $ deactivate
Create a new service named
jupyterlab
.console$ sudo nano /lib/systemd/system/jupyterlab.service
Add the following contents to the file.
ini[Unit] Description=JupyterLab Server [Service] User=USER Group=USER ExecStart=PYTHON_PATH JUPYTER_PATH lab --config=CONFIG_PATH [Install] WantedBy=multi-user.target
The above
systemd
file content creates a new service namedjupyterlab
, uses the configuration file to spawn the server. Ensure that you replace theUSER
and the*_PATH
values in the content.Save and exit the file.
Initialize the
jupyterlab
service.console$ 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.
console$ sudo apt install nginx
Swap the Nginx configuration.
console$ 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.
console$ 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.
console$ sudo snap install --classic certbot
Create a new Let's Encrypt certificate for the virtual host.
console$ 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.