[PYTHON] How to hold a hands-on seminar using Jupyter using docker

What you want to do

――Suppose you want to hold a hands-on seminar using Jupyter etc. --The execution environment will be prepared by docker. --Like Tmpnb, dynamically launch and use docker container for each student.

Realization image

arch.png

--Start a web server using python's flask. --When the seminar attendees access it, it automatically launches the container from the seminar image and redirects its address. --In the explanation below, it is confirmed by docker (1.10.2) on Ubuntu (15.10).

The web server runs both python's flask and docker. This is provided by docker, but anyway, docker runs on the host, so let's use the host environment. I will also use python by copying exe and dll from different images to volume.

Step 1. Making volume for python Tsutomu7 / py3flask (Dokcerfile with python and flask execution environment Copy the file from / blob / master / Dockerfile)) to create a volume named python. After copying the container, discard it.

bash


docker volume rm python
docker run -it --rm -v python:/usr/local tsutomu7/py3flask sh -c "\
    cp /usr/bin/python3.5 /usr/local/bin/python && \
    cp /lib/ld-musl-x86_64.so.1 /usr/local/lib && \
    ln -s /usr/local/lib/ld-musl-x86_64.so.1 /usr/local/lib/libc.musl-x86_64.so.1 && \
    cp /usr/lib/libpython3.5m.so.1.0 /usr/local/lib/ && \
    cp -r /usr/lib/python3.5/ /usr/local/lib/"

Step 2. Start server tsutomu7 / seminar (Dockerfile) Use to start the web server.

-** Specify the docker image you want the student to launch with the IMAGE environment variable **. --Specify the port number used by the image in the PORT environment variable. --If you don't have "/ lib / x86_64-linux-gnu" like CoreOS, please take that part.

bash


docker run -it --rm \
   -v /lib/x86_64-linux-gnu/:/lib/x86_64-linux-gnu/:ro \
   -v /lib64:/lib64:ro \
   -v /usr/bin:/usr/bin:ro \
   -v /usr/lib:/usr/lib:ro \
   -v /var/run/docker.sock:/var/run/docker.sock:ro \
   -v python:/usr/local \
   -p 5000:5000 \
   -e IMAGE=tsutomu7/jupyter \
   -e PORT=8888 \
   tsutomu7/seminar

Step 3. Access Access "Web server host address: 5000" with a browser from a PC connected to the network. It will automatically launch a new docker container and redirect its address. Access from the same PC is supported by one container.

A description of the server program.

Since both python and docker are borrowed, this server image is only 5MB. The program inside (seminar.py) is explained.

seminar.py


import os
from flask import Flask, request, redirect
from subprocess import run
app = Flask(__name__)
dct = {}

@app.route('/')
def hello_world():
    addr = request.environ['REMOTE_ADDR']
    if addr not in dct:
        img = os.environ.get('IMAGE', 'tsutomu7/jupyter')
        prt = os.environ.get('PORT', '8888')
        cid = 8001 + len(dct)
        run(['docker', 'run', '-d', '--name', str(cid), '-p', '%d:%s' % (cid, prt), img])
        srvr = request.environ['HTTP_HOST']
        if ':' in srvr:
            srvr = srvr[:srvr.index(':')]
        dct[addr] = 'http://%s:%d' % (srvr, cid)
    return redirect(dct[addr], 302)

if __name__ == '__main__':
    app.run('0.0.0.0', 5000)

--Use the same container for access from the same PC. The correspondence (access source address → container address) is stored in a dictionary called dct. --Enter the access source address in addr. --When addr is the first access, it does the following: --Get the image name for the student in img from the environment variable IMAGE. --In prt, get the port number used in the image from the environment variable PORT. --Calculate the port number used on the server side for the student container in cid. (Serial number from 8001) --Start the student container. --Enter the server address in srvr, delete the original port number (5000), add the port number of the new container, and set it to dct [addr]. --Redirect to dct [addr].

that's all

Recommended Posts