Jupyter Server Proxy
Jupyter Server Proxy is a Jupyter server extension that enables running arbitrary external processes (like RStudio, Shiny Server, Code Server) alongside a Jupyter notebook server and providing authenticated web access to them via proxied paths (e.g., /rstudio). It comes bundled with a JupyterLab extension to launch pre-defined processes. The current version is 4.5.0, and it generally follows a regular release cadence with bug fixes and new features, with major versions indicating potentially breaking changes.
Warnings
- breaking Version 4.0.0 introduced several breaking changes: it now requires Python 3.8+, dropped support for JupyterLab 2, and renamed the JupyterLab extension from `@jupyterlab/server-proxy` to `@jupyterhub/jupyter-server-proxy`.
- deprecated The `nbserverproxy` package is an older version and conflicts with `jupyter-server-proxy`. Installing both can lead to unexpected behavior or errors.
- gotcha When configuring proxying to *remote* hosts, simply setting `c.ServerApp.allow_remote_access = True` is insufficient. Jupyter Server Proxy uses its own `host_allowlist` configuration.
- gotcha It is a significant security concern if processes started by Jupyter Server Proxy can be accessed directly, bypassing Jupyter's authentication and authorization mechanisms.
- breaking Critical security vulnerabilities have been identified: Reflected XSS (CVE-2024-35225) due to unsanitized host parameter, and unauthenticated Websocket Proxying (CVE-2024-28179). These could allow an attacker to execute arbitrary JavaScript or bypass authentication for websocket connections.
Install
-
pip install jupyter-server-proxy -
pip install jupyter-server-proxy[standalone] -
conda install -c conda-forge jupyter-server-proxy
Imports
- ServerProxy
This is primarily configured via `jupyter_server_config.py` using `c.ServerProxy.servers`.
Quickstart
import os
# To configure jupyter-server-proxy, create or edit a file like
# ~/.jupyter/jupyter_server_config.py (or another config path)
# Example content for jupyter_server_config.py:
#
# c.ServerProxy.servers = {
# 'my-http-server': {
# 'command': ['python3', '-m', 'http.server', '{port}'],
# 'timeout': 20,
# 'launcher_entry': {
# 'title': 'My HTTP Server',
# 'enabled': True
# }
# },
# 'another-app': {
# 'command': ['sh', '-c', 'echo "Hello, {base_url}/proxy/{port}" > /tmp/output.txt && sleep 99999'],
# 'launcher_entry': {
# 'title': 'Another App',
# 'enabled': True
# }
# }
# }
print("Jupyter Server Proxy is configured via `jupyter_server_config.py`.")
print("Once configured, restart your Jupyter server.")
print("You can typically access proxied services at a URL like:")
print(" <jupyter-url>/proxy/my-http-server/")
print("Or launch from the JupyterLab Launcher if `launcher_entry` is enabled.")
# Example to demonstrate a command that could be run via the proxy (won't actually start here)
# For a real quickstart, this configuration needs to be placed in a .py config file.
# The '{port}' placeholder is crucial and is replaced by jupyter-server-proxy.
example_command = ['python3', '-m', 'http.server', '{port}']
print(f"\nExample command that can be proxied: {example_command}")