Port Forwarding with Cursor/VSCode

Screen

Introduction

  • In the Jump Host post, we used Remote-SSH so Cursor/VSCode can open files and a terminal on an HPC compute node.
  • That is enough for editing code, but JupyterLab is a web app: it listens on a port on the compute node (for example 8888), and your laptop’s browser cannot reach that port directly.
  • Port forwarding creates a secure SSH tunnel so your browser can reach services that run inside the HPC network.
  • Together with Jump Host + Remote-SSH, port forwarding is a common way to use JupyterLab on HPC from Cursor/VSCode.
  • This post focuses on dynamic port forwarding (a local SOCKS proxy), which lets the browser reach JupyterLab on a compute node through the login node.

What is Port Forwarding?

  • There are two common SSH options beginners hear about:
    • Local forwarding (-L): map one laptop port to one remote port (for example laptop 8888 → compute node 8888).
    • Dynamic forwarding (-D): open a SOCKS proxy on your laptop; the browser sends traffic through SSH, and the remote side can reach hosts inside the HPC network (including compute nodes).
  • This tutorial uses dynamic forwarding (-D). A simple picture:
Your laptop browser          SOCKS via SSH (-D)         HPC
Firefox/Chrome  ---------->  localhost:8080  ---------->  login node
   (proxy on)                (on your laptop)            then to compute node
                                                         JupyterLab (e.g. :8888)
  • Without a tunnel, your browser only sees your laptop. It cannot open the compute-node URL that JupyterLab prints.
  • With dynamic forwarding, you keep one SSH session to the login node, point the browser at a SOCKS proxy on localhost:8080, and open the JupyterLab URL that shows the compute node hostname or IP (not only 127.0.0.1 on the laptop).
  • Keep the ssh -D session open the whole time you use JupyterLab in the browser.

Step by Step tutorial

Start a dynamic SOCKS proxy

  • From a Cursor/VSCode terminal (or any local terminal), create a SOCKS proxy on your laptop and SSH to the HPC login node. Example port: 8080:
$ ssh -C -D 8080 username@hpc
  • -C: compress the SSH traffic.
  • -D 8080: start a local SOCKS proxy on your laptop at port 8080 (this is not “SSH into port 8080 on HPC”).
  • You can choose another free local port; use the same number later in the browser proxy settings.

Setup browser to use the SOCKS proxy

Firefox

  • Open Firefox settings (menu → Settings, or go to about:preferences).
  • Scroll to the bottom and open Settings under Network Settings:

Screen

  • Select Manual Proxy Configuration.
  • In SOCKS Host, enter localhost, Port 8080.
  • Check SOCKS v5.
  • Check Proxy DNS when using SOCKS v5 (so hostnames like compute-node names resolve through the tunnel).
  • Leave DNS over HTTPS off for this workflow; DoH can bypass SOCKS DNS and break HPC hostnames.
  • Make sure other proxy fields are empty/unchecked, then click OK.
  • Your settings should look like this:

Screen

Chrome or Safari

  • Set a SOCKS proxy with server localhost and port 8080 (system proxy settings on macOS, or a SOCKS-capable proxy extension on Chrome).
  • The idea is the same as Firefox: browser → localhost:8080 SOCKS → SSH → HPC.

Screen

Test the proxy with JupyterLab

  • Open a second terminal (keep the ssh -D session running). Log into HPC with regular SSH, then request a compute node:
$ ssh username@hpc
$ srun -A my_allocation -N1 -G1 -c10 --mem=64G --time=12:00:00 --pty $SHELL
  • Activate a conda environment (example name; use your own path):
$ module load conda gcc/13 cuda/12 cudnn/8.9
$ conda activate ~/tensorflow_2.17
  • Install JupyterLab if needed:
$ pip install jupyterlab
  • Start JupyterLab on the compute node (no local browser on the node):
$ jupyter lab --ip=0.0.0.0 --no-browser
  • Note: --ip=0.0.0.0 lets other nodes on the cluster reach JupyterLab. Prefer token or password auth, and stop the server when you are done.

  • The terminal will print URLs, for example:

Screen

  • Copy a URL that uses the compute node hostname or IP (or replace 127.0.0.1 with that hostname). Paste it into Firefox (with the SOCKS proxy still enabled). Through the proxy you should see JupyterLab:

Screen

  • Select your conda kernel (for example the tensorflow_2.17 environment) and check that the GPU is visible:

Screen

Troubleshoot: JupyterLab asks for a password

  • If JupyterLab requires a password, set one on the compute node before starting the server:
$ jupyter lab password