My roommate, Monica, introduced me to Jupyter Notebooks last year. And since then, I’ve been addicted to them for any Python coding I do, so much that I’m considering recreating this entire blog in Jupyter instead of WordPress.
I’m not going to get into the details of what Jupyter is, and why you should consider using it. However, to give you a broad picture, Jupyter uses the Literate Programming style pioneered by Stanford’s Donald Kunth. In this, you can have human friendly text, mathematical equations (with full LaTeX support), images or diagrams, punctuated by cells with code blocks in them. There are a lot of example notebooks available online that can be found easily, with their subjects ranging from Computer Vision, to Machine Learning, to LIGO’s dataset, and more.
However, recently I found myself trying to run a lot of Python scripts via SSH on a remote server. And while executing them in Shell has it’s pros, it was annoying when I had to make minor multiline edits earlier on in the code, because re-executing everything from scratch takes me as long as 2-3 hrs for my current project. I found myself wishing that Jupyter on my local machine could run a kernel on my server. Turns out that’s really easy to do!
Step 1: On your Remote Computer
SSH into your remote server/machine. Open a Jupyter Notebook using the no-browser option (since we don’t need the browser just yet) on the Terminal.
sasha@remote $ jupyter notebook --no-browser --port=8887
I’ve changed the port to 8887 just to make it easier to explain the next step.
Jupyter generally returns to you a token with the URL for your browser for the first time you login to it. If you get one, store this somewhere for later.
Step 2: On your Local Computer
Start an SSH Tunnel, and connect it to the Jupyter notebook you just started on the server.
ssh -N -L localhost:8888:localhost:8887 sasha@remote
-L binds the local_address:port1 to a remote_address:port2. To be specific, it specifies that the connections for the socket on the local host are to be forwarded to the remote host. The socket then listens to the specified bind address.
-N specifies not to execute a remote command. This is useful when forwarding ports.
On your local computer, navigate to localhost:8888. The browser will probably ask you for a token. Put the token the Remote Computer returned to you in the earlier step.
And that’s it!