How to Set up a JupyterLab Environment on Ubuntu 22.04

Updated on May 10, 2024
How to Set up a JupyterLab Environment on Ubuntu 22.04 header image

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.

  1. Install the virtualenv package.

    console
    $ apt update
    $ apt install python3-virtualenv
    
  2. Create a new directory and navigate into it.

    console
    $ mkdir /home/USER/jupyter-env
    $ cd /home/USER/jupyter-env
    
  3. 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 the activate binary file inside the bin directory to enter the virtual environment.

  4. Update the pip package manager.

    console
    (env) $ pip install --upgrade pip
    
  5. 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.

  1. 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.

  2. Create a new directory to organize Jupyter Notebooks.

    console
    (env) $ mkdir /home/USER/jupyter-env/notebooks
    
  3. 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.

  4. Copy and paste the below configurations.

    python
    from 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.

  5. 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.

  6. 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 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.

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.

  1. Get the paths for Python and Jupyter.

    console
    (env) $ which python
    (env) $ which jupyter
    

    Copy the paths to use them in the systemd service.

  2. Deactivate the virtual environment.

    console
    (env) $ deactivate
    
  3. Create a new service named jupyterlab.

    console
    $ sudo nano /lib/systemd/system/jupyterlab.service
    
  4. 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 named jupyterlab, uses the configuration file to spawn the server. Ensure that you replace the USER and the *_PATH values in the content.

    Save and exit the file.

  5. 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.

  1. Install the Nginx package.

    console
    $ sudo apt install nginx
    
  2. Swap the Nginx configuration.

    console
    $ sudo rm -f /etc/nginx/nginx.conf
    $ sudo nano /etc/nginx/nginx.conf
    
  3. 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.

  4. 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.

  1. Install the Certbot package.

    console
    $ sudo snap install --classic certbot
    
  2. 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.

console
$ 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.