Table of Contents

Jupyter Notebook Python Virtual Environment on DARWIN

This page is under construction.

The following steps will walk you through setting up a Conda virtual environment with Python 3 and Jupyter Notebook. It will also cover the steps of requesting a compute node to run a Jupyter Notebook session on DARWIN. Lastly, it will explain how to set up SSH connections to be able to connect to the Jupyter Notebook session from the browser on your local machine.

Before starting, make sure you set your workgroup on DARWIN. This example will demonstrate how to create a shared directory in your workgroup storage where you can create Conda environments that are accessible to everyone in your workgroup.

Before creating the Jupyter Notebook environment, start by creating a directory in your workgroup storage for Conda environments. The --mode=2775 option ensures that other people in your workgroup will also be able to create Conda environments in this directory:

[user@login00.darwin ~]$ workgroup -g my_workgroup
[(my_workgroup:user)@login00.darwin ~]$ mkdir --mode=2775 ${WORKDIR_SW}/conda-envs

Create Jupyter Notebook Virtual Environment with Conda

This example will use the Miniforge VALET package to enable usage of the Conda package manager. If you are new to Conda, make sure to review the documentation for Miniforge on DARWIN.

Start by loading the Miniforge VALET package (this command loads the default version, but you can specify a different version as needed):

[(my_workgroup:user)@login00.darwin ~]$ vpkg_require miniforge
Adding package `miniforge/25.11.0-1` to your environment

After loading Miniforge, we can now use conda create to create the Jupyter Notebook virtual environment. In this example we will call it jupyter-notebook, but you are welcome to call it anything you would like. We will specify a version directory by date 20260326 for the installation of the March 2026 Jupyter Notebook virtual environment. This is needed for setting up a VALET package definition, and allows for multiple versions to be installed based on need. Note that the list of packages to be installed is omitted from the output below.

[(my_workgroup:user)@login00.darwin ~]$ conda create --prefix=${WORKDIR_SW}/conda-envs/jupyter-notebook/20260326 python=3 jupyter
Retrieving notices: done
Channels:
 - conda-forge
Platform: linux-64
Collecting package metadata (repodata.json): done
Solving environment: done
  .
  .
  .
## Package Plan ##
 
  environment location: /lustre/my_workgroup/sw/conda-envs/jupyter-notebook/20260326
 
  added / updated specs:
    - jupyter
    - python=3
  .
  .
  .
Proceed ([y]/n)? y
  .
  .
  .
Downloading and Extracting Packages:
 
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
#     $ conda activate /lustre/my_workgroup/sw/conda-envs/jupyter-notebook/20260326
#
# To deactivate an active environment, use
#
#     $ conda deactivate

VALET Package Definition for the Virtual Environment

The new virtual environment can easily be added to your login shell and job runtime environments using VALET. Ensure you have a workgroup VALET package definition directory present, and get the path to the parent directory of your Jupyter Notebook virtual environment:

[(my_workgroup:user)@login00.darwin ~]$ ls -d ${WORKDIR_SW}/valet
/lustre/my_workgroup/sw/valet
[(my_workgroup:user)@login00.darwin ~]$ echo ${WORKDIR_SW}/conda-envs/jupyter-notebook
/lustre/my_workgroup/sw/conda-envs/jupyter-notebook

Take note of the path echoed, then create a new file in ${WORKDIR_SW}/valet named jupyter-notebook.vpkg_yaml and add the following text to it, making sure to replace my_workgroup with the name of your workgroup:

jupyter-notebook.vpkg_yaml
jupyter-notebook:
    prefix: /lustre/my_workgroup/sw/conda-envs/jupyter-notebook
    description: Jupyter Notebook virtual environments created with Conda
    flags:
        - no-standard-paths
    actions:
        - action: source
          script:
              sh: miniforge-activate.sh
          order: failure-first
          success: 0
    versions:
        "20260326":
            description: environment built March 26, 2026
            dependencies:
                - miniforge

Activating the Jupyter Notebook Virtual Environment with VALET

The versions of the virtual environment declared in the VALET package are listed using the vpkg_versions command:

[(my_workgroup:user)@login00.darwin ~]$ vpkg_versions jupyter-notebook
 
Available versions in package (* = default version):
 
[/lustre/my_workgroup/sw/valet/jupyter-notebook.vpkg_yaml]
jupyter-notebook  Jupyter Notebook virtual environments created with Conda
* 20260326        environment built March 26, 2026 

Activating the virtual environment is accomplished using the vpkg_require command (in your login shell or inside job scripts). If you load the VALET package without having first loaded the miniforge package, miniforge will also be added as a dependency:

[(my_workgroup:user)@login00.darwin ~]$ vpkg_require jupyter-notebook/20260326
Adding dependency `miniforge/25.11.0-1` to your environment
Adding package `jupyter-notebook/20260326` to your environment
(/lustre/my_workgroup/sw/conda-envs/jupyter-notebook/20260326) [(my_workgroup:user)@login00.darwin ~]$

You can deactivate the virtual environment and remove the VALET packages it depends on with:

(/lustre/my_workgroup/sw/conda-envs/jupyter-notebook/20260326) [(my_workgroup:user)@login00.darwin ~]$ vpkg_rollback
[(my_workgroup:user)@login00.darwin ~]$

Running Jupyter Notebook on DARWIN

Running Jupyter Notebook on DARWIN, or any HPC cluster for that matter, takes some extra steps. You can simply install Jupyter Notebook on your personal laptop and start it up. On DARWIN, you need to run the Jupyter Notebook on a compute node. The steps below will show you how to request an interactive compute node and use VALET to load the Jupyter Notebook virtual environment. After starting the virtual environment, we will run Jupyter Notebook with arguments that will allow for the session to be accessed via an SSH tunnel connection on your local system.

On DARWIN you're required to run Jupyter notebook on a compute node. If you run it on the login node, you could cause slowness or other issues with the login node, and IT might kill your Jupyter Notebook session without warning.

Requesting an Interactive Job

In this example we will request an interactive job to connect us to a compute node with 2GB of memory for 1 hour on the standard partition. Also it is important to pass the SLURM_EXPORT_ENV=NONE when requesting the interactive compute node. It will prevent issues with setting up a clean environment on the compute node.

[(my_workgroup:user)@login00.darwin ~]$ SLURM_EXPORT_ENV=NONE salloc --mem=2G --time=1:00:00 --partition=standard

Loading the Jupyter Notebook virtual environment

After the interactive job has been established, it is time to load the Jupyter Notebook virtual environment with VALET. Even though we did this earlier, it needs to be done again since we are now on a compute node.

[(my_workgroup:user)@r1n02 ~]$ vpkg_require jupyter-notebook/20260326
Adding dependency `miniforge/25.11.0-1` to your environment
Adding package `jupyter-notebook/20260326` to your environment
(/lustre/my_workgroup/sw/conda-envs/jupyter-notebook/20260326) [(my_workgroup:user)@r1n02 ~]$

Starting a Jupyter Notebook session

When starting the Jupyter Notebook session, specific options are passed which are used to set up the tunnel connection. You should see output similar to the following output:

(/lustre/my_workgroup/sw/conda-envs/jupyter-notebook/20260326) [(my_workgroup:user)@r1n02 ~]$ jupyter notebook --no-browser --ip=$(hostname -s)
[I 2026-03-27 15:49:27.620 ServerApp] Extension package jupyter_lsp took 2.0761s to import
[I 2026-03-27 15:49:28.268 ServerApp] Extension package jupyter_server_terminals took 0.6469s to import
[I 2026-03-27 15:49:31.083 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2026-03-27 15:49:31.093 ServerApp] jupyter_server_terminals | extension was successfully linked.
[I 2026-03-27 15:49:31.100 ServerApp] jupyterlab | extension was successfully linked.
[I 2026-03-27 15:49:31.106 ServerApp] notebook | extension was successfully linked.
[I 2026-03-27 15:49:51.486 ServerApp] notebook_shim | extension was successfully linked.
[I 2026-03-27 15:49:52.340 ServerApp] notebook_shim | extension was successfully loaded.
[I 2026-03-27 15:49:52.345 ServerApp] jupyter_lsp | extension was successfully loaded.
[I 2026-03-27 15:49:52.348 ServerApp] jupyter_server_terminals | extension was successfully loaded.
[I 2026-03-27 15:49:52.393 LabApp] JupyterLab extension loaded from /lustre/my_workgroup/sw/codna-envs/jupyter-notebook/20260326/lib/python3.14/site-packages/jupyterlab
[I 2026-03-27 15:49:52.393 LabApp] JupyterLab application directory is /lustre/my_workgroup/sw/codna-envs/jupyter-notebook/20260326/share/jupyter/lab
[I 2026-03-27 15:49:52.397 LabApp] Extension Manager is 'pypi'.
[I 2026-03-27 15:49:55.357 ServerApp] jupyterlab | extension was successfully loaded.
[I 2026-03-27 15:49:55.368 ServerApp] notebook | extension was successfully loaded.
[I 2026-03-27 15:49:55.370 ServerApp] Serving notebooks from local directory: /lustre/it_css/users/4296
[I 2026-03-27 15:49:55.370 ServerApp] Jupyter Server 2.17.0 is running at:
[I 2026-03-27 15:49:55.370 ServerApp] http://r1n02:8888/tree?token=6b177fe35204c0fdc41bdb4d40ee45c9e3074939f53ad867
[I 2026-03-27 15:49:55.371 ServerApp]     http://127.0.0.1:8888/tree?token=6b177fe35204c0fdc41bdb4d40ee45c9e3074939f53ad867
[I 2026-03-27 15:49:55.371 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 2026-03-27 15:49:55.412 ServerApp]
 
    To access the server, open this file in a browser:
        file:/home/4296/.local/share/jupyter/runtime/jpserver-40654-open.html
    Or copy and paste one of these URLs:
        http://r1n02:8888/tree?token=6b177fe35204c0fdc41bdb4d40ee45c9e3074939f53ad867
        http://127.0.0.1:8888/tree?token=6b177fe35204c0fdc41bdb4d40ee45c9e3074939f53ad867
[I 2026-03-27 15:49:55.582 ServerApp] Skipped non-installed server(s): basedpyright, bash-language-server, dockerfile-language-server-nodejs, javascript-typescript-langserver, jedi-language-server, julia-language-server, pyrefly, pyright, python-language-server, python-lsp-server, r-languageserver, sql-language-server, texlab, typescript-language-server, unified-language-server, vscode-css-languageserver-bin, vscode-html-languageserver-bin, vscode-json-languageserver-bin, yaml-language-server
At this point you will not be prompted for any further input, but the Jupyter Notebook server is running. Note the following URL in the output above:
http://r1n02:8888/tree?token=0f2f120dc34903954fb4b62dcb92e2b0c5950b670c0559ef

Before continuing, make a note of the corresponding URL from your output, since you will need it for a later step (the token and most likely the compute node name will be different for you).

Setting up SSH tunnel to connect to Jupyter Notebook server

With the Jupyter Notebook server running on a compute node on DARWIN, an SSH tunnel is needed to be able to make a connection and access the Jupyter Notebook server from a web browser on your local machine. This is done by opening a second SSH connection to DARWIN. Follow the appropriate section below for a Linux/Mac or Windows laptop.

Your compute node name will likely be different than r1n02, so please make sure to change that accordingly. This SSH tunnel connection will have to remain open while you are using Jupyter Notebook. If it is closed or internet connectivity is lost, then your connection to Jupyter Notebook will also be lost.
Linux/Mac

Open a new terminal session on your local machine. Set up an SSH tunnel using the below ssh command.

$ ssh -L 8888:r1n02:8888 user@darwin.hpc.udel.edu
Windows (Command Prompt or PowerShell)

Open a new Command Prompt or PowerShell session on your local machine. Set up an SSH tunnel using the below ssh command.

> ssh -L 8888:r1n02:8888 user@darwin.hpc.udel.edu
Windows (WSL)

Open a Linux terminal via WSL on your local machine. Set up an SSH tunnel using the below ssh command.

$ ssh -L 8888:r1n02:8888 user@darwin.hpc.udel.edu

Using your local browser to access Jupyter Notebook server

If everything so far has been set up correctly, the final step is as easy as opening a web browser of choice on your local machine and entering the correct URL. You should now use the URL that you previously made a note of from the output of the jupyter notebook command that you ran on the compute node. Change the compute node name in the URL to localhost and copy the URL into your browser. For instance, if your URL was:

http://r1n02:8888/tree?token=0f2f120dc34903954fb4b62dcb92e2b0c5950b670c0559ef

then in your browser, you would copy:

http://localhost:8888/tree?token=0f2f120dc34903954fb4b62dcb92e2b0c5950b670c0559ef

You should now see Jupyter running on your browser.

Note that since this example ran the jupyter notebook command on the compute node from the home directory ~, when you open Jupyter on your browser you will see files in your home directory on DARWIN. If you want to start from a different directory – for example, a directory where you already have a Jupyter Notebook .ipynb file that you want to open – make sure to navigate to that directory on DARWIN before starting up the Jupyter Notebook server.

If you are not able to connect to the Jupyter Notebook session at this point, then you will need to review the prior steps and make sure that you have added and configured the SSH tunnel properly based on your compute node. Remember, the SSH tunnel connection will have to remain open the entire time while you are using Jupyter Notebook.