Access your Jupyter Notebook running on Windows 10 from any computer

I recently bought a high-performance desktop to allow me to run more advanced deep learning tools. I still like to work remotely on my Macbook Pro, so I am using this setup to allow me to run Jupyter Notebooks remotely on my Macbook, but still have access to the powerful GPU on my desktop.

Note that this has been tested using Anaconda 3 and Jupyter 5.x.

I recommend first reading Running a Jupyter Server and then coming back for my Windows 10 adaptation.

First, we need to generate our config file and a default password:

PS C:\Users\joel> jupyter notebook password
Enter password:
Verify password:
[NotebookPasswordApp] Wrote hashed password to C:\Users\joel\.jupyter\jupyter_notebook_config.json

Next, open the jupyter_notebook_config.json file that was written above. You should see the sha1 of the password here. I have edited the following config items. Note the need to escape the path if you specify a notebook directory.

"NotebookApp": {
"password": "sha1:xxxxxxxxxxxxxxxxxxxxx",
"open_browser": false,
"port": 9999,
"ip": "*",
"notebook_dir": "D:\\OneDrive\\dev\\jupyter_notebooks"

Additional config options can be found here.

First, we need to get the command used to start the Jupyter Notebook. There are many ways of doing this, but the easiest is to inspect the properties of the shortcut.

Find the Jupyter Notebook in the Start Menu
Open Properties
Copy the Target

My target looked like this:

C:\Users\joel\Anaconda3\python.exe C:\Users\joel\Anaconda3\ C:\Users\joel\Anaconda3 “C:/Users/joel/Anaconda3/python.exe” “C:/Users/joel/Anaconda3/Scripts/”

Schedule to Run at Startup

Open Task Scheduler
Create a new Basic Task
Start on Computer Startup

Below, paste the first part of the command we fetched from the Shortcut target above. The rest goes in Add Arguments. Optionally specify a start in directory.

Choose to open the Properties dialog so we can continue configuration.

I chose to specify that the program will run whether I am logged on or not.

From triggers, I chose to delay the task for 30 seconds at startup.

After restarting, you should be able to visit http://localhost:9999 (or the port you specified) in order to access your notebook.

Secure the server

I recommend adding an SSL certificate in order to secure the data being sent to and from the Jupyter server.

Generating an SSL certificate on Windows 10 is significantly easier thanks to Ubuntu on Windows.

If you have Ubuntu installed, already, you can open a Bash on Ubuntu on Windows terminal (does it get any more verbose). From here, we can generate the SSL certificate and move it into the appropriate directory.

Follow the onscreen instructions
mv mykey.key /mnt/c/Users/joel/.jupyter/jupyter_server.key
mv mycert.pem /mnt/c/Users/joel/.jupyter/jupyter_server.pem

Move the files into the your .jupyter directory.

Next, we need to edit our jupyter_notebook_configuration.json in order to tell it where to find our certificate and keys.

 "NotebookApp": {
  "password": "sha1:xxxxxxxxxx",
  "open_browser": false,
  "port": 9999,
  "ip": "*",
  "notebook_dir": "D:\\OneDrive\\dev\\jupyter_notebooks",
  "certfile": "C:\\Users\\joel\\.jupyter\\jupyter.pem",
  "keyfile": "C:\\Users\\joel\\.jupyter\\jupyter.key"

Now, we can visit https://localhost:9999 and dismiss the certificate warnings. The communications are now secured.

There are additional instructions if you wish to use Lets Encrypt in the Jupyter Docs, but I won’t be covering that here.

Firewall and Port Forwarding

Open the following port ranges in your Windows Firewall, and forward the ports in your router if needed.

49152 to 65535 (used for ZeroMQ)

9999 (the port we chose to use for Jupyter)

Finally, you should be able to access your Jupyter Sever from https://[your-public-ip]:9999