Skip to content

Experimental Jupyter Features

Since 2015 Jupyter has been supported at NERSC in some form or fashion. Along the way we have expanded resources available to Jupyter users and added new features to improve their experience. Some of the work we do involves customizing our Jupyter and JupyterHub deployment and contributing back to the broader community.

We like to experiment with new features, have users test them out and give us feedback. We have created this page to provide supplemental documentation of those experimental features. If the experiments are successful we can proceed with integrating them into our production deployment. If they don't work out, well, at least we learned something!

Below you will find a list of currently experimental features that are available or under active development. For each case, there is a description of the problem it solves and how you can opt in/out of testing it. If you have feedback, opening a ticket about it is just fine. A ticket is also the best way to get help if problems arise.

If you use these features, please be sure to check this page and the update history. And finally, remember these are EXPERIMENTAL features:

  • Do not make them the mission-critical centerpiece of your project if they are listed here.
  • Expect them to develop over time, hopefully getting better, but there will be changes.
  • Please share your impressions and feedback.
  • If you learn something that would be useful to document here, please make a pull request against the docs!


Note: This used to be called the Profiles service.

JupyterLab at NERSC is managed centrally. We install the stack that you use when you start up JupyterLab on Cori or Perlmutter "bare metal." For most users this is fine, but for others it is less than ideal.

One issue is that JupyterLab extensions are installed in a bundle. This means that users have no way to install their own extensions and have them work with the central installation. This is a problem for people who need a special extension that won't be broadly useful to other users. It's also a problem if you're a user trying to actively develop your own JupyterLab extension and test it. JupyterLab 3 partially addresses this issue, but we haven't found that it takes care of all the associated issues easily.

Since we develop extensions, we needed a solution for this ourselves. We're working to generalize our solution and make it easier for users to use. The idea is that users will pick from Shifter images, conda environments, or scripts that can launch customized JupyterLab instances. These have to meet some requirements before they can be used (see below). Picking those "entrypoints" will be done on the Hub, or through a service associated with the Hub. This will allow users to choose a "default" profile other than the NERSC-provided one.

At this point in time (February 2022) we provide support for conda environment-based profiles. Shifter images can be supported to if there is a need. To handle further specialization of conda environment-based JupyterLab executables launch, we also can support wrapper-script based launch.

Trying it Out

On the main JupyterHub home page you will see a "Services" dropdown menu in the nav bar. Open it and click "entrypoint."

You will be redirected to a page listing entrypoints. To start with, you won't have any, and your selection will be "none" meaning you are using NERSC's provided JupyterLab environment. Click the "create" button under "Trusted Path Entrypoints" and you'll be redirected to a configuration page. As a test, name your entrypoint (something like "demo" would be good) and then select the demo path. It's /global/common/software/m3384/entrypoint-demo/bin. Click submit and you'll be redirected back to the entrypoint list page.

Now you should see the entrypoint you just made. Select it using the radio button: You've now changed the JupyterLab that starts up from the NERSC default to this demo. Go back to the hub's home page (click "Home" at the top left) and start a notebook up on Cori (shared CPU node). When your notebook starts up, you will notice all the usual NERSC-provided extensions (Favorites, Recent Paths, Slurm) are missing. That is because the demo doesn't have them installed. Create a new notebook and then do something like

import sys

You should see that the path to the python executable isn't what you'd normally see on Cori.

If you want to revert to the NERSC default JupyterLab, close the notebook server from the hub home page and close the notebook tab. Go back to the "entrypoint" service page and choose "none" for your custom entrypoint. Now the default JupyterLab provided by NERSC will be used again.


The main reason we have created this service and share it with users is to help projects, experiments, and groups that need a common set of Jupyter tools. It's not so each and every user can have their own JupyterLab. NERSC needs to be able to review and validate the JupyterLab installations being used.

If your group, collaboration, or project could use an entrypoint, here are the things you need to do. For all the options, you need to ensure your environment or Shifter image have these packages installed in addition to your other dependencies:

  • JupyterLab 3.x
  • JupyterHub 2.x
  • Batchspawner 1.x (available from PyPI)

Trusted Path Entrypoint

This is a path to a Conda environment, in particular to the bin directory of the environment. Create the environment and add the above dependencies to your build. Once you have that set up, open a ticket and tell us where we can find the environment. The best possible choice at NERSC is on the /global/common/software/ filesystem under your project's directory. We'll review the environment and if it looks OK, add it to the list of options and let you know it's good to go.

Trusted Script Entrypoint

Coming soon

Shifter Image Entrypoint

Coming (back) soon!

Not just any Shifter image can be used with this service. To get an image to show up here, and work properly, you need to build a Docker image:

  • Include the above 3 requirements in your build.
  • Include ENV NERSC_JUPYTER_IMAGE=YES in the Dockerfile (exactly like that)
  • Use ENV PATH=<path/to/python>:$PATH to set the path to python and jupyter-labhub
  • Push the image to a registry
  • Pull the image onto Cori/Perlmutter and convert it to Shifter with shifterimg pull <imagename>

How you set up the image is up to you. We'll create a barebones image that you could use that takes care of the first 3 of the above points. But you could start from scratch.

Once it's pulled to Cori, and if it includes the environment variable setting mentioned above, it should show up in the UI. There is a little bit of caching in the UI so it might take a minute to refresh.

Known Issues (as of 2022-02-04)

  • Shifter-based images will not run Shifter-based kernels. This may not be that big a deal since it makes sense to put everything you need into the Shifter image. The default kernel will include all your dependencies.

  • Shifter-based images cannot run Slurm commands or do module things. This may be a show-stopper for a lot of people. It isn't going to be a show-stopper for everyone.

  • The Shifter-based terminal environment may be tricky. Basically it doesn't pick up Cori's /etc/profiles directory. Work in progress.

  • There's an external dependency on the Shifter image gateway running on Cori/Perlmutter. If this goes down then you may not be able to set a new Shifter image and won't see the list. Clearing your Shifter image selection should still work in that case. If it looks like you can't select images, please alert us via ticket.