You can let users connect to their hub session with SSH for terminal work, VS Code Remote, or file transfer with scp/rsync. This runs an SSH server inside the same user container and exposes it over HTTPS.
How it works¶
jupyter-sshd-proxystartssshdinside the user server and publishes it throughjupyter-server-proxyat/sshd/over WebSockets.Authentication and authorization come from JupyterHub - no extra inbound ports or firewall changes are needed.
The SSH session uses the same CPU, memory, and storage limits as the Jupyter server.
User image requirements¶
Install the following in the user image (see Customize your user environment):
openssh-serverjupyter-sshd-proxyjupyter-server-proxy
Example values.yaml profile:
jupyterhub:
singleuser:
profileList:
- display_name: "SSH enabled"
slug: "ssh"
kubespawner_override:
image: "quay.io/yuvipanda/pangeo-jupyter-sshd-proxy:latest" # includes jupyter-sshd-proxyYou can also add these packages to your own image instead of using the example image above.
Local setup (users)¶
Install a WebSocket helper for your SSH client (recommended:
websocat).Create a JupyterHub API token from
/hub/tokenon your hub.Add an SSH config entry in
~/.ssh/config(replace placeholders):
Host myhub
HostName <your-hub-hostname> # e.g., myhub.2i2c.cloud
User jovyan
ProxyCommand websocat --binary -H="Authorization: token <API_TOKEN>" asyncstdio:wss://%h/user/<JUPYTERHUB_USERNAME>/sshd/Then connect with ssh myhub or point VS Code Remote - SSH at the myhub host. The ProxyCommand is reused by scp and rsync.
Community examples¶
Openscapes (https://
openscapes .org/) uses this workflow for VS Code Remote and large data transfers Configuration pull request: Openscapes
/openscapes .cloud #67
Acknowledgements¶
This guide was originally written by Andy Teucher for OpenScapes and its content was modified for these docs.