Background

Jupyter Lab is an open source web-based IDE for notebooks with Python and R support, geared towards the data science crowd. It’s a powerful, mature application with a potentially complex configuration. Our requirement was to deliver Jupyter Lab to users so that each user would have their own isolated “instance .” There is an off-the-shelf solution for this called Jupyter Hub that probably makes the most sense for your organization. This example will be a proof of concept on how you could roll your solution.

Step 1–Jupyter Lab Docker

If you aren’t familiar with Docker, we’re going to be using it a lot here, so check out some guides

Our first step will be getting Jupyter Lab up and running in a container. There are many Docker images available on (Docker hub)[https://hub.docker.com/] for Jupyter Lab, but since we’re rolling everything ourselves, we might as well make our own image. It also gives us more control over our code–it’s also a pretty simple Dockerfile.

FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
      python3-pip \
      python3-dev \
    && python3 -m pip install jupyterlab

EXPOSE 8888
ENTRYPOINT ["jupyter", "lab", "--ip=0.0.0.0", "--port", "8888", "--allow-root"]

There are probably some good arguments for why you should use alpine or something else as the base image here, but I’m a sucker for ubuntu. Since this isn’t a Docker tutorial, I’m not going to go into great detail here about what each line in this Dockerfile does, but assume that it installs Jupyter Lab and configures it to run at port 8888. We’ll expand on the Jupyter Lab config (and make some changes) later, but for now, this works fine.

We’re going to use Docker compose to run this. Our compose file looks like

version: "3"
services:
  jupyter:
    build:
      context: .
      dockerfile: Dockerfile
    image: jupyter
    container_name: jupyter
    ports:
      - 8888:8888

We can run this with docker compose up

This will start our Jupyter Lab container and make it available at http://127.0.0.1:8888/lab/

jupyter lab

Awesome! We’re part of the way there!

Next, we need to put together an Nginx docker file.

While we could use the official Nginx image, in keeping with the theme, we’re going to create our own Nginx image (and it’s also really simple)

FROM ubuntu:20.04

RUN apt-get update && apt-get -y install nginx
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 8000
ENTRYPOINT ["/usr/sbin/nginx"]

Pretty straightforward. Our config file is also pretty simple. We’re going to use port 8000, and we’re going to simply forward all requests directly to Jupyter lab.

daemon off;
error_log /dev/stdout info;

events {}
http {

  access_log /dev/stdout;

  upstream upstream_jupyter {
    server jupyter:8888;
    keepalive 32;
  }

  server {
    listen       8000;
    server_name  localhost;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_hide_header "X-Frame-Options";
        proxy_pass http://upstream_jupyter;
    }
  }
}

The final piece that will tie these together is our docker-compose file. Our docker-compose is pretty simple as well. By using Docker compose, the networking between the containers is handled for us, and we can point the jupyter as the service name in our nginx.conf

version: "3"
services:
  jupyter:
    build:
      context: .
      dockerfile: Dockerfile
    image: jupyter
    container_name: jupyter
    ports:
      - 8888:8888
  nginx:
    build:
      context: .
      dockerfile: nginx.Dockerfile
    image: jupyter-nginx
    container_name: nginx
    ports:
      - 8000:8000
    volumes:
      - nginx.conf:/etc/nginx/nginx.conf

Now, let’s head to http://127.0.0.1:8000, and…

nginx jupyter lab Awesome! We’re being proxied to Jupyter Lab. But, we see a page requiring token auth. This is because Jupyter is currently configured to enforce this. In the next post, we’ll deal with this and some other things regarding permissions, creating a user, and making a task definition for deploying this configuration to ECS.