From 34f47da033c4f3beb55b464515007a98b9a22e69 Mon Sep 17 00:00:00 2001 From: John Stanford Date: Mon, 4 Apr 2016 14:05:52 -0700 Subject: [PATCH] Added a Dockerfile for repeatable runtimes Builds docker image with TA-Lib, Jupyter, and checked out version of zipline and starts Jupyter server on port https://localhost:8888 when container runs. The default password for the Jupyter server is 'jupyter'. Instructions on usage found in the Dockerfile comments. Example image at docker.io/jxstanford/zipline. --- .dockerignore | 6 +++ Dockerfile | 102 ++++++++++++++++++++++++++++++++++++++++++++++ etc/docker_cmd.sh | 19 +++++++++ 3 files changed, 127 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100755 etc/docker_cmd.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..f9d081c3f5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +MANIFEST.in +**/*pyc +.eggs +dist +build +*.egg-info diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..ea1c1fb031 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,102 @@ +# +# Dockerfile for an image with the currently checked out version of zipline installed. To build: +# +# docker build -t quantopian/zipline . +# +# To run the container: +# +# docker run -v=/path/to/your/notebooks:/projects -p 8888:8888/tcp --name zipline -it quantopian/zipline +# +# To access Jupyter when running docker locally (you may need to add NAT rules): +# +# https://127.0.0.1 +# +# default password is jupyter. to provide another, see: +# http://jupyter-notebook.readthedocs.org/en/latest/public_server.html#preparing-a-hashed-password +# +# once generated, you can pass the new value via `docker run --env` the first time +# you start the container. +# +# You can also run an algo using the docker exec command. For example: +# +# docker exec -it zipline run_algo.py -f /projects/my_algo.py --start 2015-1-1 --end 2016-1-1 \ +# --symbols XOP -o /projects/result.pickle +# +# For developers who want to access source inside the zipline container, try running this from +# within the root of the zipline source tree: +# +# docker run -v=/path/to/your/notebooks:/projects -v=`pwd`:/zipline -p 443:8888/tcp \ +# --name zipline -it quantopian/zipline +# + +FROM python:2.7 + +# +# set up environment +# +ENV PROJECT_DIR=/projects \ + NOTEBOOK_PORT=8888 \ + SSL_CERT_PEM=/root/.jupyter/jupyter.pem \ + SSL_CERT_KEY=/root/.jupyter/jupyter.key \ + PW_HASH="u'sha1:31cb67870a35:1a2321318481f00b0efdf3d1f71af523d3ffc505'" \ + CONFIG_PATH=/root/.jupyter/jupyter_notebook_config.py + +# +# install TA-Lib and other prerequisites +# + +RUN mkdir ${PROJECT_DIR} \ + && apt-get -y update \ + && apt-get -y install libfreetype6-dev libpng-dev libopenblas-dev liblapack-dev gfortran \ + && curl -L http://downloads.sourceforge.net/project/ta-lib/ta-lib/0.4.0/ta-lib-0.4.0-src.tar.gz | tar xvz + +# +# build and install zipline from source. install TA-Lib after to ensure +# numpy is available. +# + +WORKDIR /ta-lib + +RUN pip install numpy==1.9.2 \ + && pip install scipy==0.15.1 \ + && pip install pandas==0.16.1 \ + && ./configure --prefix=/usr \ + && make \ + && make install \ + && pip install TA-Lib \ + && pip install jupyter + +# +# This is then only file we need from source to remain in the +# image after build and install. +# + +ADD ./etc/docker_cmd.sh / + +# +# make port available. /zipline is made a volume +# for developer testing. +# +EXPOSE ${NOTEBOOK_PORT} + +# +# build and install the zipline package into the image +# + +ADD . /zipline +WORKDIR /zipline +RUN python setup.py install + +# +# clean up the build artifacts and recreate the folder for +# developer mount +# + +RUN rm -rf /zipline && mkdir /zipline + +# +# start the jupyter server +# + +WORKDIR ${PROJECT_DIR} +CMD /docker_cmd.sh diff --git a/etc/docker_cmd.sh b/etc/docker_cmd.sh new file mode 100755 index 0000000000..801b10be46 --- /dev/null +++ b/etc/docker_cmd.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# +# generate configuration, cert, and password if this is the first run +# +if [ ! -f /var/tmp/zipline_init ] ; then + jupyter notebook --generate-config + if [ ! -f ${SSL_CERT_PEM} ] ; then + openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=127.0.0.1" \ + -keyout ${SSL_CERT_KEY} -out ${SSL_CERT_PEM} + fi + echo "c.NotebookApp.password = ${PW_HASH}" >> ${CONFIG_PATH} + touch /var/tmp/zipline_init +fi + +jupyter notebook -y --no-browser --notebook-dir=${PROJECT_DIR} \ + --certfile=${SSL_CERT_PEM} --keyfile=${SSL_CERT_KEY} --ip='*' \ + --config=${CONFIG_PATH}