|
| 1 | +# Port Forwarding for Jupyter and HPC Jobs |
| 2 | + |
| 3 | +This guide explains how to securely and effectively forward ports from a compute node on the SWC HPC cluster to your local machine, enabling access to services like Jupyter Lab. This is particularly useful when `code tunnel` is unreliable or you prefer using a terminal-based workflow. |
| 4 | + |
| 5 | +Port forwarding allows you to interact with services running on a compute node (e.g., a Jupyter server on port 8082) from your browser or other tools on your laptop. |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +The technique described below **does not involve SSHing into unallocated nodes**, which could interfere with other users or violate HPC usage policies. Instead, you'll **only access a node you've been assigned by SLURM**, and will **forward ports from that node to your laptop**, enabling tools like Jupyter Lab to work as expected without disconnection issues. |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +## Step-by-step Instructions |
| 14 | + |
| 15 | +### 1. Connect to the cluster and request an interactive job |
| 16 | + |
| 17 | +```bash |
| 18 | +ssh <SWC-USERNAME>@ssh.swc.ucl.ac.uk |
| 19 | +ssh hpc-gw2 |
| 20 | +``` |
| 21 | + |
| 22 | +Then request a SLURM interactive job. For example: |
| 23 | + |
| 24 | +```bash |
| 25 | +srun --nodes=1 --ntasks-per-node=1 --cpus-per-task=8 -p a100 --gres=gpu:1 --time=96:00:00 --mem=41G --pty bash -i |
| 26 | +``` |
| 27 | + |
| 28 | +This will assign you a compute node and give you an interactive shell there. |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +### 2. Set up and launch Jupyter Lab |
| 33 | + |
| 34 | +On the assigned node, activate your environment and navigate to your project folder: |
| 35 | + |
| 36 | +```bash |
| 37 | +pyenv activate my_venv_3115 |
| 38 | +cd /path/to/your/project |
| 39 | +``` |
| 40 | + |
| 41 | +Then launch Jupyter Lab, specifying a port (e.g., 8082) and disabling the browser: |
| 42 | + |
| 43 | +```bash |
| 44 | +jupyter lab --no-browser --port=8082 |
| 45 | +``` |
| 46 | + |
| 47 | +Jupyter will start and display a link with a token. |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +### 3. Forward the port from the compute node to your local machine |
| 52 | + |
| 53 | +On **your local machine**, open a separate terminal and run: |
| 54 | + |
| 55 | +```bash |
| 56 | +ssh -L 8082:localhost:8082 <node-name> |
| 57 | +``` |
| 58 | + |
| 59 | +Replace `<node-name>` with the actual name of the compute node assigned to you (e.g., `gpu-sr670-20`). This command establishes a secure tunnel between your laptop and the node. |
| 60 | + |
| 61 | +Then, **in your browser**, go to: |
| 62 | + |
| 63 | +``` |
| 64 | +http://localhost:8082 |
| 65 | +``` |
| 66 | + |
| 67 | +Paste in the token provided by the `jupyter lab` output. |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +### 4. Notes on usage and cluster rules |
| 72 | + |
| 73 | +This method **respects cluster usage policies** because: |
| 74 | + |
| 75 | +- You are only SSHing into a node **you were explicitly allocated by SLURM**. |
| 76 | +- The port forwarding (`ssh -L`) only gives you access to services running **on the localhost of that node**, not to shared resources. |
| 77 | + |
| 78 | +:::note |
| 79 | +Using `ssh -L` on an allocated node is generally considered safe, as long as you're not trying to bypass SLURM's resource management or share your access with others. |
| 80 | +::: |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +## When to use this method |
| 85 | + |
| 86 | +You may prefer this method when: |
| 87 | + |
| 88 | +- `code tunnel` times out frequently or becomes unreliable. |
| 89 | +- You don't need a full GUI like VSCode but still want access to Jupyter or HTTP apps. |
| 90 | +- You're comfortable with the command line and prefer manual control over your environment. |
| 91 | + |
| 92 | +--- |
| 93 | + |
| 94 | +## Troubleshooting |
| 95 | + |
| 96 | +- **Jupyter not accessible at `localhost:8082`?** Make sure the ports match exactly in both commands. |
| 97 | +- **Timeouts or connection drops?** Ensure you're using the assigned node and haven't closed the original SLURM session. |
| 98 | +- **Port already in use?** Try another port like `8888`, `8090`, etc., just remember to update both commands. |
| 99 | + |
| 100 | +--- |
| 101 | + |
| 102 | +## Complementary tools |
| 103 | + |
| 104 | +If you prefer a fully integrated development environment and are okay with occasional tunnel issues, see our guide on: |
| 105 | + |
| 106 | +[Using VSCode with Interactive SLURM Jobs →](./vscode-tunnel.md) |
| 107 | + |
| 108 | +--- |
| 109 | + |
| 110 | +## Examples for Other Web Applications |
| 111 | + |
| 112 | +### Dash Applications |
| 113 | + |
| 114 | +For Dash applications, you can follow the same port forwarding approach: |
| 115 | + |
| 116 | +1. **On the compute node**, launch your Dash app with a specific port: |
| 117 | + |
| 118 | +```bash |
| 119 | +python app.py |
| 120 | +``` |
| 121 | + |
| 122 | +Where your `app.py` contains: |
| 123 | + |
| 124 | +```python |
| 125 | +from dash import Dash, html, dcc |
| 126 | +import dash_bootstrap_components as dbc |
| 127 | + |
| 128 | +app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) |
| 129 | + |
| 130 | +app.layout = html.Div([ |
| 131 | + html.H1("My Dash App"), |
| 132 | + dcc.Graph(id='example-graph') |
| 133 | +]) |
| 134 | + |
| 135 | +if __name__ == '__main__': |
| 136 | + app.run_server(debug=False, host='0.0.0.0', port=8050) |
| 137 | +``` |
| 138 | + |
| 139 | +2. **On your local machine**, forward the port: |
| 140 | + |
| 141 | +```bash |
| 142 | +ssh -L 8050:localhost:8050 <node-name> |
| 143 | +``` |
| 144 | + |
| 145 | +3. **Access your app** at `http://localhost:8050` |
| 146 | + |
| 147 | +### Streamlit Applications |
| 148 | + |
| 149 | +For Streamlit applications: |
| 150 | + |
| 151 | +1. **On the compute node**, launch Streamlit with a specific port: |
| 152 | + |
| 153 | +```bash |
| 154 | +streamlit run app.py --server.port 8501 --server.address 0.0.0.0 |
| 155 | +``` |
| 156 | + |
| 157 | +2. **On your local machine**, forward the port: |
| 158 | + |
| 159 | +```bash |
| 160 | +ssh -L 8501:localhost:8501 <node-name> |
| 161 | +``` |
| 162 | + |
| 163 | +3. **Access your app** at `http://localhost:8501` |
| 164 | + |
| 165 | +### Flask/FastAPI Applications |
| 166 | + |
| 167 | +For Flask or FastAPI applications: |
| 168 | + |
| 169 | +1. **On the compute node**, launch your app: |
| 170 | + |
| 171 | +```bash |
| 172 | +# For Flask |
| 173 | +python app.py |
| 174 | + |
| 175 | +# For FastAPI |
| 176 | +uvicorn main:app --host 0.0.0.0 --port 8000 |
| 177 | +``` |
| 178 | + |
| 179 | +2. **On your local machine**, forward the port: |
| 180 | + |
| 181 | +```bash |
| 182 | +ssh -L 8000:localhost:8000 <node-name> |
| 183 | +``` |
| 184 | + |
| 185 | +3. **Access your app** at `http://localhost:8000` |
| 186 | + |
0 commit comments