Add example for deploying notebook container using Docker Compose.

(c) Copyright IBM Corp. 2016
This commit is contained in:
Justin Tyberg
2016-02-15 18:21:04 -05:00
parent 9f9907cf1d
commit b87886633f
15 changed files with 481 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
# Pick your favorite docker-stacks image
FROM jupyter/minimal-notebook:55d5ca6be183
USER jovyan
# Add permanent pip/conda installs, data files, other user libs here
# e.g., RUN pip install jupyter_dashboards
USER root
# Add permanent apt-get installs and other root commands here
# e.g., RUN apt-get install npm nodejs

View File

@@ -0,0 +1,96 @@
Run a docker-stack notebook container using Docker Compose on a Docker Machine-controlled host.
## Pre-requisites
* [Docker Engine](https://docs.docker.com/engine/) 1.10.0+
* [Docker Machine](https://docs.docker.com/machine/) 0.6.0+
* [Docker Compose](https://docs.docker.com/compose/) 1.6.0+
See the [installation instructions](https://docs.docker.com/engine/installation/) for your environment.
## Quickstart
Here's how to build and run a `jupyter/minimal-notebook` container on an existing Docker machine.
```
# activate docker machine
eval "$(docker-machine env mymachine)"
# build notebook image on the machine
notebook/build.sh
# bring up notebook container
notebook/up.sh
```
To stop and remove the container:
```
notebook/down.sh
```
## FAQ
### Can I run multiple notebook containers on the same VM?
Yes. Set environment variables to specify unique names and ports when running the `up.sh` command.
```
NAME=my-notebook PORT=9000 notebook/up.sh
NAME=your-notebook PORT=9001 notebook/up.sh
```
To stop and remove the containers:
```
NAME=my-notebook notebook/down.sh
NAME=your-notebook notebook/down.sh
```
### Where are my notebooks stored?
The `up.sh` creates a Docker volume named after the notebook container with a `-work` suffix, e.g., `my-notebook-work`.
### Can multiple notebook containers share the same notebook volume?
Yes. Set the `WORK_VOLUME` environment variable to the same value for each notebook.
```
NAME=my-notebook PORT=9000 WORK_VOLUME=our-work notebook/up.sh
NAME=your-notebook PORT=9001 WORK_VOLUME=our-work notebook/up.sh
```
### How do I run over HTTPS?
To run the notebook server with a self-signed certificate, pass the `--secure` option to the `up.sh` script. You must also provide a password, which will be used to secure the notebook server. You can specify the password by setting the `PASSWORD` environment variable, or by passing it to the `up.sh` script.
```
PASSWORD=a_secret notebook/up.sh --secure
# or
notebook/up.sh --secure --password a_secret
```
To use a real certificate from Let's Encrypt, first run the `bin/letsencrypt.sh` script to create the certificate chain and store it in a Docker volume.
```
FQDN=host.mydomain.com EMAIL=myemail@somewhere.com bin/letsencrypt.sh
```
The following command will store the certificate chain in a Docker volume named `mydomain-secrets`.
```
FQDN=host.mydomain.com EMAIL=myemail@somewhere.com \
SECRETS_VOLUME=mydomain-secrets \
bin/letsencrypt.sh
```
Now run `up.sh` with the `--letsencrypt` option. You must also provide the name of the secrets volume and a password.
```
PASSWORD=a_secret SECRETS_VOLUME=mydomain-secrets notebook/up.sh --letsencrypt
# or
notebook/up.sh --letsencrypt --password a_secret --secrets mydomain-secrets
```

View File

@@ -0,0 +1,11 @@
#!/bin/bash
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Setup environment
source "$DIR/env.sh"
# Build the notebook image
docker-compose -f "$DIR/notebook.yml" build

View File

@@ -0,0 +1,11 @@
#!/bin/bash
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Setup environment
source "$DIR/env.sh"
# Bring down the notebook container, using container name as project name
docker-compose -f "$DIR/notebook.yml" -p "$NAME" down

View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
# Set default values for environment variables required by notebook compose
# configuration file.
# Container name
: "${NAME:=my-notebook}"
export NAME
# Exposed container port
: ${PORT:=80}
export PORT
# Container work volume name
: "${WORK_VOLUME:=$NAME-work}"
export WORK_VOLUME
# Container secrets volume name
: "${SECRETS_VOLUME:=$NAME-secrets}"
export SECRETS_VOLUME

View File

@@ -0,0 +1,30 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
version: "2"
services:
notebook:
build: .
image: my-notebook
container_name: ${NAME}
volumes:
- "work:/home/jovyan/work"
- "secrets:/etc/letsencrypt"
ports:
- "${PORT}:8888"
environment:
USE_HTTPS: "yes"
PASSWORD: ${PASSWORD}
command: >
start-notebook.sh
--NotebookApp.certfile=/etc/letsencrypt/fullchain.pem
--NotebookApp.keyfile=/etc/letsencrypt/privkey.pem
volumes:
work:
external:
name: ${WORK_VOLUME}
secrets:
external:
name: ${SECRETS_VOLUME}

View File

@@ -0,0 +1,19 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
version: "2"
services:
notebook:
build: .
image: my-notebook
container_name: ${NAME}
volumes:
- "work:/home/jovyan/work"
ports:
- "${PORT}:8888"
volumes:
work:
external:
name: ${WORK_VOLUME}

View File

@@ -0,0 +1,22 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
version: "2"
services:
notebook:
build: .
image: my-notebook
container_name: ${NAME}
volumes:
- "work:/home/jovyan/work"
ports:
- "${PORT}:8888"
environment:
USE_HTTPS: "yes"
PASSWORD: ${PASSWORD}
volumes:
work:
external:
name: ${WORK_VOLUME}

View File

@@ -0,0 +1,72 @@
#!/bin/bash
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
set -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
USAGE="Usage: `basename $0` [--secure | --letsencrypt] [--password PASSWORD] [--secrets SECRETS_VOLUME]"
# Parse args to determine security settings
SECURE=${SECURE:=no}
LETSENCRYPT=${LETSENCRYPT:=no}
while [[ $# > 0 ]]
do
key="$1"
case $key in
--secure)
SECURE=yes
;;
--letsencrypt)
LETSENCRYPT=yes
;;
--secrets)
SECRETS_VOLUME="$2"
shift # past argument
;;
--password)
PASSWORD="$2"
export PASSWORD
shift # past argument
;;
*) # unknown option
;;
esac
shift # past argument or value
done
if [[ "$LETSENCRYPT" == yes || "$SECURE" == yes ]]; then
if [ -z "${PASSWORD:+x}" ]; then
echo "ERROR: Must set PASSWORD if running in secure mode"
echo "$USAGE"
exit 1
fi
if [ "$LETSENCRYPT" == yes ]; then
CONFIG=letsencrypt-notebook.yml
if [ -z "${SECRETS_VOLUME:+x}" ]; then
echo "ERROR: Must set SECRETS_VOLUME if running in letsencrypt mode"
echo "$USAGE"
exit 1
fi
else
CONFIG=secure-notebook.yml
fi
export PORT=${PORT:=443}
else
CONFIG=notebook.yml
export PORT=${PORT:=80}
fi
# Setup environment
source "$DIR/env.sh"
# Create a Docker volume to store notebooks
docker volume create --name "$WORK_VOLUME"
# Bring up a notebook container, using container name as project name
echo "Bringing up notebook '$NAME'"
docker-compose -f "$DIR/$CONFIG" -p "$NAME" up -d
IP=$(docker-machine ip $(docker-machine active))
echo "Notebook $NAME listening on $IP:$PORT"