Remote Jupyter Lab: how to utilize Jupyter Lab to its fullest on a remote server?
Jupyter Lab and remote servers.
One of the main reasons I use Jupyter Lab as my data science workbench is that it is based entirely on a web browser. This means that you don’t have to care about system compatibility or accessibility, you only need to set up a Conda environment, run Jupyter Lab, and you’ll be able to access it from anywhere in the world. Although I’m not a big fan of Jupyter Lab when it comes to bigger, non research-oriented projects, when I’m doing deep learning research, I find Jupyter Lab to be most at home.
In this article, I wish to share some of the techniques I use when I work on a project with Jupyter Lab running off a remote GPU server.
Run Jupyter Lab with internet-wide accessibility
I work off of my remote server which has more “horsepower” for deep learning and other jobs. The only way I can access my server is via SSH, which exposes only a terminal session to my local machine. This is not enough. While VS Code do have the well-established “Remote-SSH” plugin, which allows it to connect to the server as if it were working directly on your local machine, VS Code’s SSH connection doesn’t work well with servers behind a proxy.
Currently, due to the COVID-19 outbreak, I’m doing my research from home, and my server is only accessible from inside my school’s LAN. Fortunately, I have deployed a jump server which enables me to access my school’s network via a VMESS protocol — a protocol often used to avoid censorship. My current means of connection to my remote server is shown in the diagram below.
You can see that I’m connecting to the GPU server with the VMESS proxy jump server’s help. This is achieved by my running a local VMESS session, and then connecting through this local-to-jump-server VMESS proxy tunnel to my remote GPU server via SSH. In this way, I can access all my school LAN’s resources as if I were at school.
I initiate the proxied SSH session with a simple tool called proxychains
. You can download it with most package managers on macOS and Linux distributions. Below is a simple GIF demo.
After gaining access to the GPU server. We can run Jupyter Lab with the following command inside a Conda environment:
$ jupyter lab --no-browser
This initializes Jupyter Lab without launching an external browser, which is suitable for our usage on a remote server. However, Jupyter Lab’s web front-end process listens on 127.0.0.1:8888
by default. The default localhost IP 127.0.0.1
means that we can only access Jupyter Lab on the machine it’s currently running off of. This is where the trick begins: we can set Jupyter Lab to listen on IP 0.0.0.0
, thus, allowing external web access.
$ jupyter lab --no-browser --ip="0.0.0.0"
This launches our Jupyter Lab instance with internet-wide access, which means we can access our Jupyter Lab directly by going through the same VMESS proxy server we used when initiating our SSH session. You can set your local machine’s browser proxy to our local VMESS proxy server’s address, and access your remote server by {IP:PORT}
, which is 10.x.x.x:8888
in my case.
SSH port forwarding (tunneling)
Exposing a Jupyter Lab instance to the public internet is often not the best case when it comes to security. To make things more safe, we can make use of our existing SSH session. SSH has a feature which allows us to forward a specific port onto our local machine. Using this feature, we can connect to our remote instance of Jupyter Lab with a secure SSH tunnel.
First, we need to initialize a Jupyter Lab instance on our remote server’s 127.0.0.1:8888
(Yes, we don’t have to expose the remote server to the entire LAN with 0.0.0.0
anymore!). After logging onto the remote server via SSH, I often enter a tmux
session first, in order to preserve logs:
$ tmux
Then, I’ll run Jupyter Lab as always on the remote server (default port 8888):
$ jupyter lab --no-browser
Doing so, we should have a running Jupyter Lab listening on the remote server’s 127.0.0.1:8888
. After this, we can safely log out of the server with the Jupyter Lab instance running on our server in the background. (Just closing the terminal will be okay, you don’t need to quit the tmux
session.) We’ll then connect to this instance via our secure SSH tunnel. Back on our local machine, we simply run:
$ ssh -N -L 8888:localhost:8888 {user}@{server_ip}
This command forwards the remote port 8888
onto our local machine’s port 8888
. Note you will need to change {user}
and {server_ip}
to your own.
The diagram below shows our basic principles when we utilize SSH port forwarding.
And now, we can directly access our Jupyter Lab running on our remote server by simply going to 127.0.0.1:8888
on our local machine’s web browser!
Conclusion
I find that running Jupyter Lab and forwarding its port to my local device most useful, and maybe more secure. I hope this tutorial will benefit your experience when working off a remote environment. Thank you for reading.