Skip to content

Use custom_display_url (or a dedicated public URL) for open_browser #1590

@sonnymilton

Description

@sonnymilton

Problem

When running Jupyter Server / JupyterLab behind a reverse proxy (Caddy, nginx, etc), the server typically binds to a local address such as 127.0.0.1:8888, while users access it via a stable URL like https://jupyter.local/.

Jupyter provides the ServerApp.custom_display_url option, which correctly prints the public URL (including the token) in the startup logs. However, when ServerApp.open_browser=True is enabled, Jupyter still opens the browser using the bind address (http://127.0.0.1:8888/...) instead of the public URL. This happens even though the correct public URL is already known and displayed.

As a result, users running Jupyter behind a reverse proxy with TLS and a custom hostname must either manually open the printed URL or implement wrapper scripts/workarounds to open the correct address.

Proposed Solution

When ServerApp.open_browser=True and ServerApp.custom_display_url is set, use custom_display_url as the base URL for opening the browser (including the correct path and token), instead of the local bind address.

Alternatively, introduce a dedicated configuration option (for example, ServerApp.public_url or ServerApp.browser_open_url) that explicitly controls which URL is used when opening the browser, while keeping custom_display_url as a display-only setting for logs.

Additional context

  • Typical setup: Jupyter Server / JupyterLab behind a reverse proxy (Caddy, Nginx, Traefik) with a local bind address (127.0.0.1:8888) and a public HTTPS URL.
  • custom_display_url already solves the problem of displaying the correct URL to the user, but open_browser does not currently respect it.
  • Current workarounds include disabling open_browser and opening the correct URL manually or via wrapper scripts (e.g. parsing the token from jupyter server list and calling xdg-open).
  • Supporting this behavior natively would improve the developer experience for local and self-hosted Jupyter setups using reverse proxies and TLS.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions