Skip to content

Instantly share code, notes, and snippets.

@whlteXbread
Last active June 4, 2019 20:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whlteXbread/c9c949db66daab011c32d5dcd42686fe to your computer and use it in GitHub Desktop.
Save whlteXbread/c9c949db66daab011c32d5dcd42686fe to your computer and use it in GitHub Desktop.
Two ways to access your fastai Jupiter Notebook

Accessing Your [fast-ai, AWS] Jupyter Notebook from Anywhere

Some networks out in the world don't allow traffic on all ports. For the most part though, HTTP is open just about everywhere.

As we know, Jupyter notebooks don't operate on the standard HTTP port. What follows are a couple ways to use commonly open ports to access your notebook.

I'll discuss two methods, both with their advantages and disadvantages:

  • Using SSH to tunnel HTTP traffic through an open SSH port

    • Advantages

      • One command makes your notebook available
      • Notebook is externally accessable only to those who can authenticate with the machine
      • Data is encrypted in transit
    • Disadvantages

      • The port SSH uses (port 22) isn't open on all networks
  • Running a web server [nginx] on your AWS instance to serve your Jupyter notebook

    • Advantages:

      • If your instance is running, your notebook is available with no hassle
      • Once you've set it up you don't need to worry about whether you can access your notebook on a given network
    • Disadvantages:

      • Not hard as far as linux goes, but not for the faint of heart
      • Data transmitted in the clear

Hopefully that helps you decide what you want to do.

SSH Tunneling

Here's what you need to do to use SSH Tunneling to access your notebook.

  1. run this command in your shell:
     ssh -N -L localhost:8889:[AWS-IP-ADDRESS]:8888 ubuntu@[AWS-IP-ADDRESS] -i ~/.ssh/aws-key-fast-ai.pem
  1. Access your notebook in your browser at localhost:8889 —ezpz.
  2. When you're finished, bush CTRL + C to close the connection.

I suppose somebody could even add this to the aws-alias.sh script and make a pull request :)

Alternatively you can run the following command if you want the SSH tunnel to run in the background and you're comfortable killing the process when you're finished with it:

     ssh -N -f -L localhost:8889:[AWS-IP-ADDRESS]:8888 ubuntu@[AWS-IP-ADDRESS] -i ~/.ssh/aws-key-fast-ai.pem

Running a Web Server

What follows is a little bit more thorough explanation of these directions.

  1. Open port 80 on the AWS instance.

    • You can do this either by modifying the security groups in the EC2 console or by using the AWS CLI.
  2. Start the instance and open a terminal.

  3. Install nginx.

     sudo apt-get install nginx
  1. Create a script to run Jupyter Notebook as a daemon.

Instructions for Ubuntu 14.04

* First create this file: `/etc/init/jupyternb.conf`
* Paste the following into that file:
      description "jupyter notebook service"
      author      "this guy"

      start on filesystem or runlevel [2345]
      stop on shutdown
      respawn

      script
          echo $$ > /var/run/jupyter.pid
          exec sudo -u ubuntu -H /home/ubuntu/anaconda2/bin/jupyter notebook --no-browser --NotebookApp.allow_origin='*' --notebook-dir=/home/ubuntu/nbs

      end script

      pre-stop script
          rm /var/run/jupyter.pid
      end script

Instructions for Ubuntu 16.04 (GPU instances)

  • First create this file: /etc/systemd/system/jupyternb.service
  • Paste the following into that file:
      [Unit]
      Description=Jupyter Notebook

      [Service]
      Type=simple
      PIDFile=/run/jupyter.pid
      ExecStart=/home/ubuntu/anaconda2/bin/jupyter-notebook --no-browser --NotebookApp.allow_origin='*' --notebook-dir=/home/ubuntu/nbs
      User=ubuntu
      Group=ubuntu
      WorkingDirectory=/home/ubuntu/nbs/
      Restart=always
      RestartSec=10
      #KillMode=mixed

      [Install]
      WantedBy=multi-user.target
* Enable the service:
      sudo systemctl enable jupyternb.service
  1. Edit the following block of code so your AWS IP is the server name:
      upstream notebook {
          server localhost:8888;
      }
      server{
      listen 80;
      server_name [AWS_IP_ADDRESS];
      location / {
              proxy_pass            http://notebook;
              proxy_set_header      Host $host;
      }

      location ~ /api/kernels/ {
              proxy_pass            http://notebook;
              proxy_set_header      Host $host;
              # websocket support
              proxy_http_version    1.1;
              proxy_set_header      Upgrade "websocket";
              proxy_set_header      Connection "Upgrade";
              proxy_read_timeout    86400;
          }
      location ~ /terminals/ {
              proxy_pass            http://notebook;
              proxy_set_header      Host $host;
              # websocket support
              proxy_http_version    1.1;
              proxy_set_header      Upgrade "websocket";
              proxy_set_header      Connection "Upgrade";
              proxy_read_timeout    86400;
      }
      }

Or, if you want to get super fancy, set up a domain name and have your AWS instance update your DNS server dynamically so you don't have to use Amazon's elastic IP.

  1. Put the contents of that file in this location:
      /etc/nginx/sites-available/jupyter
  1. Tell nginx to use the configuration we just made
      sudo ln -s /etc/nginx/sites-available/jupyter /etc/nginx/sites-enabled/jupyter
  1. Check that file is configured properly:
      sudo nginx -t
  1. Start Jupyter daemon (it will also start anytime the machine is booted):
      sudo service jupyternb start
  1. Start the nginx server:
      sudo service nginx start
  1. Access your notebook by typing whatever you put into the server_name block.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment