Docker Reverse Proxy Jupyter Notebook

Docker Reverse Proxy Jupyter Notebook

Data Science and Docker - two great tastes that go great together! In this episode we look at a quick and easy way to integrate Jupyter Notebooks (Data Science Edition) with a docker project using Nginx as a Reverse Proxy.

For reference, you might want to check out another Nginx Docker article I wrote (link to the right). This Jupyter Notebook service  will dovetail nicely into that project with no substantial modification.

However, if you just want to do a standalone Jupyter Notebook install with Nginx, this project should fit the bill...

Let's kick things off by adding the following service definition to our docker-compose.yml file:

jupyter:
image: jupyter/datascience-notebook
volumes:
- ./work:/home/jovyan/work
ports:
- "8888:8888"
# We are permanently setting our token
command: [start-notebook.sh, --NotebookApp.token='supersecrettokencode']
restart: always

Starting with our docker-compile.yml file, what does this all do?

  • image: Find more Jupyter stacks here: http://dockr.ly/2kyitUG
  • volumes: map to external folder for notebook persistence
  • ports: we're opening up the default 8888
  • command: create static token

Nginx Configuration

Now let's turn our attention to .conf file you'll want to add to your nginx/conf.d directory (or available-sites directory depending on how you like to roll your Nginx...)

We start by leveraging Nginx's upstream ngx_http_module to proxy pass traffic off to our Jupyter notebook server process. We listen to requests coming into port 80 from our mysiteurl.com URL and then pass these through. We also need to use websockets for the kernels and terminals we might spawn in our environement.

Make sure you include the last proxy_set_header "Origin"; in the event you run into any timeout or buffering issues.

upstream jupyter {
server localhost:8888;
}
server{
listen 80;
server_name "mysiteurl.com";
location / {
proxy_pass            http://jupyter;
proxy_set_header      Host $host;
}

location ~ /api/kernels/ {
proxy_pass            http://jupyter;
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;
proxy_set_header Origin "";

}
location ~ /terminals/ {
proxy_pass            http://jupyter;
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;
proxy_set_header Origin "";
}
}

At this point the only thing left to do is add the above to a conf file in your nginx/conf.d directory, add the docker-compile.yml snippet to your project and docker-compile up -d the thing.

Also happy dance, because that was pretty simple...