Port Forwarding with Cursor/VSCode

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 laptop8888→ compute node8888). - 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).
- Local forwarding (
- 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 only127.0.0.1on the laptop). - Keep the
ssh -Dsession 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 port8080(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:

- Select Manual Proxy Configuration.
- In SOCKS Host, enter
localhost, Port8080. - 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:

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

Test the proxy with JupyterLab
- Open a second terminal (keep the
ssh -Dsession 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.0lets 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:

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

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

Troubleshoot: JupyterLab asks for a password
- If JupyterLab requires a password, set one on the compute node before starting the server:
$ jupyter lab password