diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..4df07f9df9 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +.PHONY: build dev help + +OWNER:=jupyter +STACK?= + +help: + @echo + @echo 'build STACK= - build using Dockerfile in named directory' + @echo ' dev STACK= - run container using stack name' + @echo + +build: + @cd $(STACK) && \ + docker build --rm --force-rm -t $(OWNER)/$(STACK) . + +dev: + docker run -it --rm -p 8888:8888 $(OWNER)/$(STACK) \ No newline at end of file diff --git a/README.md b/README.md index d530393c03..1cfe09aa42 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ # docker-stacks -Stacks of Jupyter applications+kernels, in docker + +Opinionated stacks of ready-to-run Jupyter applications in Docker. + +## Quick Start + +If you already have Docker configured and know exactly what you'd like to run, this one-liner is for you: + +``` +docker run -d -P jupyter/ +``` + +## Getting Started + +If this is your first time using Docker or any of the Jupyter projects, do the following to get started. + +1. [Install Docker](https://docs.docker.com/installation/) on your host of choice. +2. Click the folder for your desired stack on GitHub. +3. Follow the README in that stack. diff --git a/minimal-notebook/Dockerfile b/minimal-notebook/Dockerfile new file mode 100644 index 0000000000..bce451d2e1 --- /dev/null +++ b/minimal-notebook/Dockerfile @@ -0,0 +1,71 @@ +FROM debian:jessie + +MAINTAINER Jupyter Project + +# Install all OS dependencies for fully functional notebook server +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update && apt-get install -yq --no-install-recommends \ + git \ + vim \ + wget \ + build-essential \ + python-dev \ + ca-certificates \ + bzip2 \ + unzip \ + libsm6 \ + pandoc \ + texlive-latex-base \ + texlive-latex-extra \ + texlive-fonts-extra \ + texlive-fonts-recommended \ + supervisor \ + sudo \ + && apt-get clean + +ENV CONDA_DIR /opt/conda +ENV NB_USER jovyan + +# Install conda +RUN echo 'export PATH=$CONDA_DIR/bin:$PATH' > /etc/profile.d/conda.sh && \ + wget --quiet https://repo.continuum.io/miniconda/Miniconda3-3.9.1-Linux-x86_64.sh && \ + /bin/bash /Miniconda3-3.9.1-Linux-x86_64.sh -b -p $CONDA_DIR && \ + rm Miniconda3-3.9.1-Linux-x86_64.sh && \ + $CONDA_DIR/bin/conda install --yes conda==3.14.1 + +# Create non-root user +RUN useradd -m -s /bin/bash $NB_USER +RUN chown -R $NB_USER:$NB_USER $CONDA_DIR +RUN chown $NB_USER:$NB_USER /home/$NB_USER -R + +# Configure user environment +USER $NB_USER +ENV HOME /home/$NB_USER +ENV SHELL /bin/bash +ENV USER $NB_USER +ENV PATH $CONDA_DIR/bin:$PATH + +# Setup a work directory rooted in home for ease of volume mounting +ENV WORK $HOME/work +RUN mkdir -p $WORK +WORKDIR $WORK + +# Install Jupyter notebook +RUN conda install --yes \ + ipython-notebook==3.2 \ + terminado \ + && conda clean -yt + +# Configure Jupyter +RUN ipython profile create + +# Configure container startup +EXPOSE 8888 +USER root +CMD ["supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"] + +# Add local files as late as possible to avoid cache busting +COPY ipython_notebook_config.py $HOME/.ipython/profile_default/ +COPY notebook.conf /etc/supervisor/conf.d/ +COPY enable_sudo.sh /usr/local/bin/ +RUN chown $NB_USER:$NB_USER $HOME/.ipython/profile_default/ipython_notebook_config.py \ No newline at end of file diff --git a/minimal-notebook/README.md b/minimal-notebook/README.md new file mode 100644 index 0000000000..b74b799b4a --- /dev/null +++ b/minimal-notebook/README.md @@ -0,0 +1,26 @@ +# Minimal Jupyter Notebook Stack + +## What it Gives You + +* Jupyter Notebook server v3.2.x +* Conda Python 3.4.x +* No preinstalled scientific computing packages +* Options for HTTPS, password auth, and passwordless `sudo` + +## Basic Use + +The following command starts a container with the Notebook server listening for HTTP connections on port 8888 without authentication configured. + +``` +docker run -d -p 8888:8888 jupyter/minimal-notebook +``` + +## Options + +You may customize the execution of the Docker container and the Notebook server it contains with the following optional arguments. + +* `-e PASSWORD="YOURPASS"` - Configures Jupyter Notebook to require the given password. Should be conbined with `USE_HTTPS` on untrusted networks. +* `-e USE_HTTPS=yes` - Configures Jupyter Notebook to accept encrypted HTTPS connections. If a `pem` file containing a SSL certificate and key is not found in `/home/jovyan/.ipython/profile_default/security/notebook.pem`, the container will generate a self-signed certificate for you. +* `-e GRANT_SUDO=yes` - Gives the `jovyan` user passwordless `sudo` capability. Useful for installing OS packages. **You should only enable `sudo` if you trust the user or if the container is running on an isolated host.** +* `-v /some/host/folder/for/work:/home/jovyan/work` - Host mounts the default working directory on the host to preserve work even when the container is destroyed and recreated (e.g., during an upgrade). +* `-v /some/host/folder/for/server.pem:/home/jovyan/.ipython/profile_default/security/notebook.pem` - Mounts a SSL certificate plus key for `USE_HTTPS`. Useful if you have a real certificate for the domain under which you are running the Notebook server. \ No newline at end of file diff --git a/minimal-notebook/enable_sudo.sh b/minimal-notebook/enable_sudo.sh new file mode 100755 index 0000000000..fb2a777112 --- /dev/null +++ b/minimal-notebook/enable_sudo.sh @@ -0,0 +1,4 @@ +#!/bin/bash +if [ ! -z "$GRANT_SUDO" ]; then + echo "$NB_USER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/notebook +fi \ No newline at end of file diff --git a/minimal-notebook/ipython_notebook_config.py b/minimal-notebook/ipython_notebook_config.py new file mode 100644 index 0000000000..4d35c32902 --- /dev/null +++ b/minimal-notebook/ipython_notebook_config.py @@ -0,0 +1,25 @@ +import subprocess +import os + +PEM_FILE = os.path.join(os.path.dirname(__file__), 'security/notebook.pem') + +c = get_config() +c.NotebookApp.ip = '*' +c.NotebookApp.open_browser = False +c.NotebookApp.port = 8888 + +# Set a certificate if USE_HTTPS is set to any value +if 'USE_HTTPS' in os.environ: + if not os.path.isfile(PEM_FILE): + # Generate a certificate if one doesn't exist on disk + subprocess.check_call(['openssl', 'req', '-new', + '-newkey', 'rsa:2048', '-days', '365', '-nodes', '-x509', + '-subj', '/C=XX/ST=XX/L=XX/O=generated/CN=generated', + '-keyout', PEM_FILE, '-out', PEM_FILE]) + c.NotebookApp.certfile = PEM_FILE + +# Set a password if PASSWORD is set +if 'PASSWORD' in os.environ: + from IPython.lib import passwd + c.NotebookApp.password = passwd(os.environ['PASSWORD']) + del os.environ['PASSWORD'] \ No newline at end of file diff --git a/minimal-notebook/notebook.conf b/minimal-notebook/notebook.conf new file mode 100644 index 0000000000..1246fb9384 --- /dev/null +++ b/minimal-notebook/notebook.conf @@ -0,0 +1,18 @@ +[program:notebook] +user=jovyan +umask=0002 +directory=/home/jovyan/work +command=ipython notebook +autostart=true +autorestart=true +stdout_logfile=/var/log/supervisor/%(program_name)s.log +redirect_stderr=true + +[program:sudoers] +command=enable_sudo.sh +autostart=true +autorestart=false +stdout_logfile=/var/log/supervisor/%(program_name)s.log +redirect_stderr=true +startretries=0 +startsecs=0 diff --git a/r-notebook/Dockerfile b/r-notebook/Dockerfile new file mode 100644 index 0000000000..cb6f6c93ee --- /dev/null +++ b/r-notebook/Dockerfile @@ -0,0 +1,36 @@ +FROM jupyter/minimal-notebook + +MAINTAINER Jupyter Project + +# R pre-requisites +RUN apt-get install -y --no-install-recommends \ + libxrender1 \ + fonts-dejavu \ + gfortran \ + gcc && apt-get clean + +USER jovyan + +# R packages +RUN conda config --add channels r +RUN conda install --yes \ + 'r-base=3.1*' \ + 'r-irkernel=0.4*' \ + 'r-plyr=1.8*' \ + 'r-devtools=1.7*' \ + 'r-dplyr=0.4*' \ + 'r-ggplot2=1.0*' \ + 'r-tidyr=0.2*' \ + 'r-shiny=0.11*' \ + 'r-rmarkdown=0.5*' \ + 'r-forecast=5.8*' \ + 'r-stringr=0.6*' \ + 'r-rsqlite=1.0*' \ + 'r-reshape2=1.4*' \ + 'r-nycflights13=0.1*' \ + 'r-caret=6.0*' \ + 'r-rcurl=1.95*' \ + 'r-randomforest=4.6*' && conda clean -yt + +# Switch back to root so that supervisord runs under that user +USER root \ No newline at end of file diff --git a/r-notebook/README.md b/r-notebook/README.md new file mode 100644 index 0000000000..325522fe3d --- /dev/null +++ b/r-notebook/README.md @@ -0,0 +1,26 @@ +# Jupyter Notebook R Stack + +## What it Gives You + +* Jupyter Notebook server v3.2.x +* Conda R v3.1.x and channel +* plyr, devtools, dplyr, ggplot2, tidyr, shiny, rmarkdown, forecast, stringr, rsqlite, reshape2, nycflights13, caret, rcurl, and randomforest pre-installed +* Options for HTTPS, password auth, and passwordless `sudo` + +## Basic Use + +The following command starts a container with the Notebook server listening for HTTP connections on port 8888 without authentication configured. + +``` +docker run -d -p 8888:8888 jupyter/r-notebook +``` + +## Options + +You may customize the execution of the Docker container and the Notebook server it contains with the following optional arguments. + +* `-e PASSWORD="YOURPASS"` - Configures Jupyter Notebook to require the given password. Should be conbined with `USE_HTTPS` on untrusted networks. +* `-e USE_HTTPS=yes` - Configures Jupyter Notebook to accept encrypted HTTPS connections. If a `pem` file containing a SSL certificate and key is not found in `/home/jovyan/.ipython/profile_default/security/notebook.pem`, the container will generate a self-signed certificate for you. +* `-e GRANT_SUDO=yes` - Gives the `jovyan` user passwordless `sudo` capability. Useful for installing OS packages. **You should only enable `sudo` if you trust the user or if the container is running on an isolated host.** +* `-v /some/host/folder/for/work:/home/jovyan/work` - Host mounts the default working directory on the host to preserve work even when the container is destroyed and recreated (e.g., during an upgrade). +* `-v /some/host/folder/for/server.pem:/home/jovyan/.ipython/profile_default/security/notebook.pem` - Mounts a SSL certificate plus key for `USE_HTTPS`. Useful if you have a real certificate for the domain under which you are running the Notebook server. \ No newline at end of file diff --git a/scipy-notebook/Dockerfile b/scipy-notebook/Dockerfile new file mode 100644 index 0000000000..e5c7daed73 --- /dev/null +++ b/scipy-notebook/Dockerfile @@ -0,0 +1,49 @@ +FROM jupyter/minimal-notebook + +MAINTAINER Jupyter Project + +USER jovyan + +# Install Python 3 packages +RUN conda install --yes \ + 'pandas=0.16*' \ + 'matplotlib=1.4*' \ + 'scipy=0.15*' \ + 'seaborn=0.6*' \ + 'scikit-learn=0.16*' \ + 'scikit-image=0.11*' \ + 'sympy=0.7*' \ + 'cython=0.22*' \ + 'patsy=0.3*' \ + 'statsmodels=0.6*' \ + 'cloudpickle=0.1*' \ + 'dill=0.2*' \ + 'numba=0.20*' \ + 'bokeh=0.9*' \ + && conda clean -yt + +# Install Python 2 packages and kernel spec +RUN conda create -p $CONDA_DIR/envs/python2 python=2.7 \ + 'ipython=3.2*' \ + 'pandas=0.16*' \ + 'matplotlib=1.4*' \ + 'scipy=0.15*' \ + 'seaborn=0.6*' \ + 'scikit-learn=0.16*' \ + 'scikit-image=0.11*' \ + 'sympy=0.7*' \ + 'cython=0.22*' \ + 'patsy=0.3*' \ + 'statsmodels=0.6*' \ + 'cloudpickle=0.1*' \ + 'dill=0.2*' \ + 'numba=0.20*' \ + 'bokeh=0.9*' \ + pyzmq \ + && conda clean -yt +RUN $CONDA_DIR/envs/python2/bin/python \ + $CONDA_DIR/envs/python2/bin/ipython \ + kernelspec install-self --user + +# Switch back to root so that supervisord runs under that user +USER root \ No newline at end of file diff --git a/scipy-notebook/README.md b/scipy-notebook/README.md new file mode 100644 index 0000000000..9f729fc830 --- /dev/null +++ b/scipy-notebook/README.md @@ -0,0 +1,26 @@ +# Jupyter Notebook Scientific Python Stack + +## What it Gives You + +* Jupyter Notebook server v3.2.x +* Conda Python 3.4.x and Python 2.7.x environments +* pandas, matplotlib, scipy, seaborn, scikit-learn pre-installed +* Options for HTTPS, password auth, and passwordless `sudo` + +## Basic Use + +The following command starts a container with the Notebook server listening for HTTP connections on port 8888 without authentication configured. + +``` +docker run -d -p 8888:8888 jupyter/scipy-notebook +``` + +## Options + +You may customize the execution of the Docker container and the Notebook server it contains with the following optional arguments. + +* `-e PASSWORD="YOURPASS"` - Configures Jupyter Notebook to require the given password. Should be conbined with `USE_HTTPS` on untrusted networks. +* `-e USE_HTTPS=yes` - Configures Jupyter Notebook to accept encrypted HTTPS connections. If a `pem` file containing a SSL certificate and key is not found in `/home/jovyan/.ipython/profile_default/security/notebook.pem`, the container will generate a self-signed certificate for you. +* `-e GRANT_SUDO=yes` - Gives the `jovyan` user passwordless `sudo` capability. Useful for installing OS packages. **You should only enable `sudo` if you trust the user or if the container is running on an isolated host.** +* `-v /some/host/folder/for/work:/home/jovyan/work` - Host mounts the default working directory on the host to preserve work even when the container is destroyed and recreated (e.g., during an upgrade). +* `-v /some/host/folder/for/server.pem:/home/jovyan/.ipython/profile_default/security/notebook.pem` - Mounts a SSL certificate plus key for `USE_HTTPS`. Useful if you have a real certificate for the domain under which you are running the Notebook server. \ No newline at end of file