{"id":6387,"library":"jupyter-server-proxy","title":"Jupyter Server Proxy","description":"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.","status":"active","version":"4.5.0","language":"en","source_language":"en","source_url":"https://github.com/jupyterhub/jupyter-server-proxy","tags":["jupyter","proxy","server","jupyterlab","jupyterhub","extension"],"install":[{"cmd":"pip install jupyter-server-proxy","lang":"bash","label":"Standard Installation"},{"cmd":"pip install jupyter-server-proxy[standalone]","lang":"bash","label":"Installation with Standalone Proxy"},{"cmd":"conda install -c conda-forge jupyter-server-proxy","lang":"bash","label":"Conda Installation"}],"dependencies":[{"reason":"Core dependency as it's a Jupyter server extension. Implicitly required for versions >=4.0.0.","package":"jupyter_server","optional":false},{"reason":"Required for the bundled JupyterLab extension. JupyterLab >=3,<5 is supported.","package":"JupyterLab","optional":true},{"reason":"Required for the 'standalone' proxy feature.","package":"JupyterHub","optional":true}],"imports":[{"note":"Jupyter Server Proxy is typically configured through Jupyter's configuration system (traitlets in files like `jupyter_server_config.py`) rather than direct Python imports in user application code. Direct imports like `from jupyter_server_proxy.handlers import ProxyHandler` or `from jupyter_server_proxy.config import ServerProxy` are for advanced use cases like building custom extensions or programmatic configuration, not common end-user interaction.","symbol":"ServerProxy","correct":"This is primarily configured via `jupyter_server_config.py` using `c.ServerProxy.servers`."}],"quickstart":{"code":"import os\n\n# To configure jupyter-server-proxy, create or edit a file like\n# ~/.jupyter/jupyter_server_config.py (or another config path)\n# Example content for jupyter_server_config.py:\n#\n# c.ServerProxy.servers = {\n#     'my-http-server': {\n#         'command': ['python3', '-m', 'http.server', '{port}'],\n#         'timeout': 20,\n#         'launcher_entry': {\n#             'title': 'My HTTP Server',\n#             'enabled': True\n#         }\n#     },\n#     'another-app': {\n#         'command': ['sh', '-c', 'echo \"Hello, {base_url}/proxy/{port}\" > /tmp/output.txt && sleep 99999'],\n#         'launcher_entry': {\n#             'title': 'Another App',\n#             'enabled': True\n#         }\n#     }\n# }\n\nprint(\"Jupyter Server Proxy is configured via `jupyter_server_config.py`.\")\nprint(\"Once configured, restart your Jupyter server.\")\nprint(\"You can typically access proxied services at a URL like:\")\nprint(\"  <jupyter-url>/proxy/my-http-server/\")\nprint(\"Or launch from the JupyterLab Launcher if `launcher_entry` is enabled.\")\n\n# Example to demonstrate a command that could be run via the proxy (won't actually start here)\n# For a real quickstart, this configuration needs to be placed in a .py config file.\n# The '{port}' placeholder is crucial and is replaced by jupyter-server-proxy.\nexample_command = ['python3', '-m', 'http.server', '{port}']\nprint(f\"\\nExample command that can be proxied: {example_command}\")","lang":"python","description":"To use jupyter-server-proxy, you typically create a configuration file (e.g., `jupyter_server_config.py`) in your Jupyter config directory (often `~/.jupyter/`). In this file, you define the external processes you want to proxy using the `c.ServerProxy.servers` traitlet. The `command` list specifies how to start the process, with `{port}` being a mandatory placeholder that jupyter-server-proxy replaces with an available port. After configuring and restarting your Jupyter server, the proxied services become accessible via URLs like `<jupyter-url>/proxy/<server-name>/` or through launcher entries in JupyterLab if specified."},"warnings":[{"fix":"Ensure your environment meets Python 3.8+ and JupyterLab 3+ requirements. Update any references to the old JupyterLab extension name.","message":"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`.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Uninstall `nbserverproxy` before installing `jupyter-server-proxy` using `pip uninstall nbserverproxy`.","message":"The `nbserverproxy` package is an older version and conflicts with `jupyter-server-proxy`. Installing both can lead to unexpected behavior or errors.","severity":"deprecated","affected_versions":"All versions when `nbserverproxy` is also installed."},{"fix":"Use `c.ServerProxy.host_allowlist = ['example.com', '192.168.1.1']` (or a similar list of allowed hosts) in your `jupyter_server_config.py`.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always ensure that the proxied processes are only accessible through the Jupyter Server's proxy endpoint. A common strategy is to run Jupyter Server within a container and restrict network access to only the Jupyter Server itself.","message":"It is a significant security concern if processes started by Jupyter Server Proxy can be accessed directly, bypassing Jupyter's authentication and authorization mechanisms.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Upgrade to jupyter-server-proxy 4.5.0 or later immediately to patch these vulnerabilities.","message":"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.","severity":"breaking","affected_versions":"<4.5.0"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z"}