So, here is what I am trying to achieve:
- A Jupyterhub server
- Which when accessed and you are not logged in, takes you to another web server (custom coded in Django)
- That web server uses OAuth to authenticate a user
- And a notebook container is spawned.
- This notebook container must be pre-populated with a token that is used by a custom library baked into the notebook Docker image to authenticate against a service.
- The notebook container needs to be able to communicate with the web server for further interactions like retrieve results etc.
I have more or less achieved this except for the last part. I am getting a notebook server started but it has no access to the outside world. It can only access the Jupyter Hub (that's why it works!) and nothing else.
Here is my Jupyter Hub config relevant to the DockerSpawner (I'm leaving out the OAuth settings since these work as expected.
# Tell JupyterHub that we want Docker Spawner to be used.
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
# And what image should be used by the Docker Spawner
c.DockerSpawner.image = 'jupyter/scipy-notebook:7a0c7325e470'
# The Hub must listen on all interfaces.
c.JupyterHub.hub_ip = '0.0.0.0'
# And this should be the address of the Hub API
c.JupyterHub.hub_connect_ip = 'jupyterhub'
# Ask containers to connect to this network so that they can
# communicate with the Hub.
c.DockerSpawner.network_name = 'djangodockerjupyterdemo_default'
# And let's not make a mess, remove user containers when done.
c.DockerSpawner.remove = True
# We need to set the Notebook Directory
notebook_dir = '/home/jovyan/work'
c.DockerSpawner.notebook_dir = notebook_dir
# Need to tell where to mount the volumes.
c.DockerSpawner.volumes = { 'jupyterhub-user-{username}': notebook_dir }
Please note that djangodockerjupyterdemo_default is being created by docker-compose thanks to the name of the project directory being such. (I know this is not the best thing to do but right now I'm just hoping to have a bare minimal example working.)
Here is my docker-compose:
version: "2"
services:
database:
image: "mysql:5.6"
volumes:
- ./data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=test123
- MYSQL_DATABASE=oauthserver
- MYSQL_USER=oauthadmin
- MYSQL_PASSWORD=test123
webapp:
image: auth_server:latest
volumes:
- ./:/app
links:
- database:database
environment:
- PYTHONUNBUFFERED=1
- ENV=DEV
- DATABASE_HOST=database
- DATABASE_USER=oauthadmin
- DATABASE_DBNAME=oauthserver
- DATABASE_PASSWORD=test123
hostname: oauthserver.ddi.in
jupyterhub:
image: "jupyterhub:test"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:rw"
- "./jupyterhub:/srv/jupyterhub"
environment:
- OAUTH2_AUTHORIZE_URL=http://oauthserver.ddi.in:8000/o/authorize
- OAUTH2_TOKEN_URL=http://oauthserver.ddi.in:8000/o/token/
hostname: jhtest.ddi.in
links:
- webapp:oauthserver.ddi.in
I use https://hub.docker.com/r/defreitas/dns-proxy-server to access the JupyterHub server by saying "http://jhtest.ddi.in:8000".
Now, once the containers are up, here is what I can confirm:
docker execing intowebapporjupyterhubcontainers and thenwgeting a file from some place on the Internet works.docker execing into the spawned Jupyter notebook container and doing the same doesn't. Same goes with trying to userequests.get()from inside the notebook.
How can I make the spawned notebook access the outside world? It's critical for my use case (and I'm sure a reasonable expectation).
PS: I notice there are hardly any examples covering OAuth JupyterHub setup with a custom Django application out there. I hope to publish my example publicly and hopefully it can constitute as a resource on the Jupyter Hub docs.