We are pleased to announce the release of JupyterHub 0.8. This is a big release with many fixes and improvements, and some major changes.

To upgrade from jupyterhub 0.7:

Stop jupyterhub pip3 install --upgrade jupyterhub==0.8 Backup your database: e.g. cp -v jupyterhub.sqlite jupyterhub-backup-$(date +%Y-%m-%d).sqlite Upgrade your database: jupyterhub upgrade-db

See the changelog for more details. The “Notes on Upgrading” below also provides more specifics.

OAuth

Perhaps the biggest change is the switch to using OAuth 2.0 for the internal authentication mechanism in JupyterHub. This shouldn’t have much of a visible effect on your deployments other than hopefully a reduction in redirect-loops when users login.

If you are writing a JupyterHub Service, then you can switch to OAuth by using the HubOAuthenticated or HubOAuth classes if you were previously using HubAuthenticated or HubAuth . All of these classes now support token-based access via the Authorization header, just like the Hub itself.

Stability, Scalability, and Performance

As part of supporting larger deployments, we have done some scalability stress testing of the Hub, finding and fixing several race conditions that could manifest as redirect loops, bugs, and performance improvements when the Hub is under load. This has been led largely by the Berkeley Data Science Education Program team, which has over one thousand students using a JupyterHub instance this Fall. We now know that one JupyterHub 0.8 instance can support a few thousand users logging in and attempting to spawn their servers at the same time. Once servers are active, the Hub is minimally involved, and the proxy becomes the next bottleneck.

Custom Proxy Implementations

Another major new feature targeted at scalability is custom proxy implementations. JupyterHub has always used Configurable-HTTP-Proxy (CHP), a single-process Node.js HTTP proxy. This is a single process bottleneck and potential single point of failure for Hub deployments. CHP can handle a lot of concurrent active users (at least several thousand), but for larger scale applications, Hub deployments may want to use a more scalable and/or robust proxy implementation.

To achieve this, JupyterHub 0.8 introduces a Python API abstracting the proxy needs of JupyterHub and developers can provide their own proxy implementations as alternatives to CHP. The first such implementation uses a Kubernetes Traefik-based Ingress for the proxy, as part of KubeSpawner.

Persisting Authentication State

Another new feature available to Authenticators is the encrypted persistence of authentication state. This is aimed at preserving and passing authenticator-related state, such as client certificates or GitHub API tokens. Authenticators provided by oauthenticator 0.7 support persisting auth state from upstream authentication services.

Other Highlights

Preliminary (API-only, no GUI) support for multiple named servers per user

Token-based access to the single-user server API

A page for users to request new API tokens from the Hub

Notes on upgrading

As with every update to JupyterHub, make sure to back-up your database and run upgrade-db . For example, if using JupyterHub with SQLite:

Backup: cp -v jupyterhub.sqlite jupyterhub-backup-$(date +%Y-%m-%d).sqlite Upgrade: jupyterhub upgrade-db

Due to the change in internal authentication, it is important that you make sure that single-user servers and the Hub itself are upgraded at the same time. If you are running everything in one env (e.g. the default Spawner, SudoSpawner, or similar), there is nothing to do. However, if you are using a container-based setup to launch single-user server (e.g. DockerSpawner or KubeSpawner), make sure that your user image and your Hub both get the upgrade at the same time. In most cases, this means adding to your Dockerfile:

RUN pip3 install jupyterhub==0.8.0

which ensures the correct version of JupyterHub is installed.

Thanks to everyone who has contributed to this release, especially users who have helped out with testing JupyterHub during the beta process, which helps make this a great release!