diff --git a/README.md b/README.md index 0a7c15d..e54337a 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,17 @@ # jupyterhub-deploy-docker -The **jupyterhub-deploy-docker** repository provides a reference +**jupyterhub-deploy-docker** provides a reference deployment of [JupyterHub](https://github.com/jupyter/jupyterhub), a multi-user [Jupyter Notebook](http://jupyter.org/) environment, on a **single host** using [Docker](https://docs.docker.com). -Possible **use cases** for this deployment may include, but are not -limited to: +Possible **use cases** include, but are not limited to: -* A JupyterHub demo environment that you can spin up relatively quickly. -* A multi-user Jupyter Notebook environment for small classes, teams, - or departments. +* Creating a JupyterHub demo environment that you can spin up relatively + quickly. +* Providing a multi-user Jupyter Notebook environment for small classes, + teams, or departments. **Disclaimer:** This deployment is **NOT** intended for a production environment. @@ -51,82 +51,115 @@ Key components of this reference deployment are: ## Prerequisites -* **Docker**: This deployment uses Docker for all the things, via - [Docker Compose](https://docs.docker.com/compose/overview/). It - requires [Docker Engine](https://docs.docker.com/engine) 1.12.0 or - higher. Use the [Docker installation instructions](https://docs.docker.com/engine/installation/) - for your environment. - -* **HTTPS and SSL**: This deployment configures JupyterHub to use HTTPS - connections (the default). You must provide TLS certificate chain and - key files in the JupyterHub configuration. If you do not have an - existing certificate chain and key, you can [create self-signed versions](https://jupyter-notebook.readthedocs.org/en/latest/public_server.html#using-ssl-for-encrypted-communication), - or obtain real ones from [Let's Encrypt](https://letsencrypt.org) - (see the [letsencrypt example](examples/letsencrypt/README.md) for - instructions). +### Docker -To verify that you are set up with docker, via a local installation or -[docker-machine](./docs/docker-machine.md), run: +This deployment uses Docker for all the things, via [Docker Compose](https://docs.docker.com/compose/overview/). +[Docker Engine](https://docs.docker.com/engine) 1.12.0 or higher is +required. Use [Docker's installation instructions](https://docs.docker.com/engine/installation/) +to set up Docker for your environment. + +To verify your docker installation, whether running docker as a local installation or using [docker-machine](./docs/docker-machine.md), +enter these commands: ```bash + docker version docker ps ``` -This command will return running Docker processes. + + +### HTTPS and SSL/TLS certificate + +This deployment configures JupyterHub to use HTTPS connections (the +default). You must provide TLS certificate chain and key file in the +JupyterHub configuration. + +1. Obtain the domain name that you wish to use for JupyterHub, for + example, `myfavoritesite.com` or `jupiterplanet.org`. + +1. If you do not have an existing certificate chain and key, you can +[create self-signed versions](https://jupyter-notebook.readthedocs.org/en/latest/public_server.html#using-ssl-for-encrypted-communication), +or obtain real ones from [Let's Encrypt](https://letsencrypt.org) +(see the [letsencrypt example](examples/letsencrypt/README.md) for +instructions). + +1. Copy the certificate chain and key files for the JupyterHub server +to a directory named `secrets` within this repository directory. +These will be added to the JupyterHub Docker image at build time. For +example, create a `secrets` directory in the root of this repo and +copy the certificate and key files (`jupyterhub.crt` and `jupyterhub.key`) +to this directory: + +```bash + mkdir -p secrets + cp jupyterhub.crt jupyterhub.key secrets/ +``` ## Authenticator setup This deployment uses GitHub OAuth to authenticate users. -It requires that you create a [GitHub application](https://github.com/settings/applications/new). -You will need to specify an OAuth callback URL in the following form: + +It requires that you create and register a [GitHub OAuth application](https://github.com/settings/applications/new) +by filling out a form on the GitHub site: + +![GitHub OAuth application form](docs/oauth-form.png) + +In this form, you will specify the OAuth application's callback URL in +this format: ``` https:///hub/oauth_callback ``` -You must pass the secrets that GitHub provides for your application to JupyterHub at runtime. -You can do this by setting the `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, -and `OAUTH_CALLBACK_URL` environment variables when you run the JupyterHub container, -or you can add them to the `.env` file in the root directory of this repository. For example, +After submitting the GitHub form, your registered GitHub OAuth +application is assigned a unique Client ID and Client Secret. The +Client Secret should be kept private. -``` -GITHUB_CLIENT_ID= -GITHUB_CLIENT_SECRET= -OAUTH_CALLBACK_URL=https:///hub/oauth_callback -``` +You must pass the GitHub OAuth Client ID, Client Secret and OAuth +callback url to JupyterHub at runtime. You can do this by either: -**Note:** The `.env` file is a special file that Docker Compose uses to lookup environment variables. -If you choose to place the GitHub secrets in this file, -you should ensure that this file remains private -(e.g., do not commit the secrets to source control). +- setting the `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, and + `OAUTH_CALLBACK_URL` environment variables when you run the + JupyterHub container, or +- add them to the `.env` file in the root directory of this repository. + For example, update the following lines in the `.env` file: + + **.env** + ``` + GITHUB_CLIENT_ID= + GITHUB_CLIENT_SECRET= + OAUTH_CALLBACK_URL=https:///hub/oauth_callback + ``` + + **Note:** The `.env` file is a special file that Docker Compose uses + to lookup environment variables. If you choose to place the GitHub + OAuth application settings in this file, you should make sure that the + file remains private (be careful to not commit the `.env` file with + these secrets to source control). ## Build the JupyterHub Docker image -Configure JupyterHub and build it into a Docker image. +Configure JupyterHub -1. Copy the TLS certificate chain and key files for the JupyterHub server to a directory named `secrets` within this repository directory. These will be added to the JupyterHub Docker image at build time. If you do not have a certificate chain and key, you can either [create self-signed versions](https://jupyter-notebook.readthedocs.org/en/latest/public_server.html#using-ssl-for-encrypted-communication), or obtain real ones from [Let's Encrypt](https://letsencrypt.org) (see the [letsencrypt example](examples/letsencrypt/README.md) for instructions). - - ``` - mkdir -p secrets - cp jupyterhub.crt jupyterhub.key secrets/ - ``` +and build it into a Docker image. 1. Create a `userlist` file with a list of authorized users. At a minimum, this file should contain a single admin user. The username should be a GitHub username. For example: - ``` +**file** +``` jtyberg admin - ``` +``` The admin user will have the ability to add more users in the JupyterHub admin console. 1. Use [docker-compose](https://docs.docker.com/compose/reference/) to build the JupyterHub Docker image on the active Docker machine host: - ``` +```bash make build - ``` +``` ## Spawner: Prepare the Jupyter Notebook Image @@ -159,7 +192,7 @@ Notebook server that is compatible with JupyterHub). You can pull the image using the following command: -``` +```bash make notebook_image ``` @@ -170,19 +203,20 @@ Run the JupyterHub container on the host. To run the JupyterHub container in detached mode: -``` +```bash docker-compose up -d ``` Once the container is running, you should be able to access the JupyterHub console at +**file** ``` https://myhost.mydomain ``` To bring down the JupyterHub container: -``` +```bash docker-compose down ``` @@ -192,6 +226,14 @@ docker-compose down `make build` does a few things behind the scenes, to set up the environment for JupyterHub: +### Create a JupyterHub Data Volume + +Create a Docker volume to persist JupyterHub data. This volume will reside on the host machine. Using a volume allows user lists, cookies, etc., to persist across JupyterHub container restarts. + +```bash +docker volume create --name jupyterhub-data +``` + ### Create a Docker Network Create a Docker network for inter-container communication. The benefits of using a Docker network are: @@ -201,18 +243,10 @@ Create a Docker network for inter-container communication. The benefits of usin Here we create a Docker network named `jupyterhub-network`. Later, we will configure the JupyterHub and single-user Jupyter Notebook containers to run attached to this network. -``` +```bash docker network create jupyterhub-network ``` -### Create a JupyterHub Data Volume - -Create a Docker volume to persist JupyterHub data. This volume will reside on the host machine. Using a volume allows user lists, cookies, etc., to persist across JupyterHub container restarts. - -``` -docker volume create --name jupyterhub-data -``` - --- ## FAQ @@ -221,7 +255,7 @@ docker volume create --name jupyterhub-data Use `docker logs `. For example, to view the logs of the `jupyterhub` container -``` +```bash docker logs jupyterhub ``` @@ -235,7 +269,7 @@ JupyterHub reads the Notebook image name from `jupyterhub_config.py`, which reads the Notebook image name from the `DOCKER_NOTEBOOK_IMAGE` environment variable: -``` +```python # DockerSpawner setting in jupyterhub_config.py c.DockerSpawner.container_image = os.environ['DOCKER_NOTEBOOK_IMAGE'] ``` @@ -243,6 +277,7 @@ c.DockerSpawner.container_image = os.environ['DOCKER_NOTEBOOK_IMAGE'] By default, the`DOCKER_NOTEBOOK_IMAGE` environment variable is set in the `.env` file. +**file** ``` # Setting in the .env file DOCKER_NOTEBOOK_IMAGE=jupyter/scipy-notebook:2d878db5cbff @@ -254,7 +289,7 @@ by setting the `DOCKER_NOTEBOOK_IMAGE` variable to a different Notebook image in the environment where you launch JupyterHub. For example, the following setting would be used to spawn single-user `pyspark` notebook servers: -``` +```bash export DOCKER_NOTEBOOK_IMAGE=jupyterhub/pyspark-notebook:2d878db5cbff docker-compose up -d @@ -282,25 +317,25 @@ There are multiple ways to [backup and restore](https://docs.docker.com/engine/u Suppose you have the following running containers: -``` -docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Names}}" +```bash + docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Names}}" -CONTAINER ID IMAGE NAMES -bc02dd6bb91b jupyter/minimal-notebook jupyter-jtyberg -7b48a0b33389 jupyterhub jupyterhub + CONTAINER ID IMAGE NAMES + bc02dd6bb91b jupyter/minimal-notebook jupyter-jtyberg + 7b48a0b33389 jupyterhub jupyterhub ``` In this deployment, the user's notebook directories (`/home/jovyan/work`) are backed by Docker volumes. -``` -docker inspect -f '{{ .Mounts }}' jupyter-jtyberg +```bash + docker inspect -f '{{ .Mounts }}' jupyter-jtyberg -[{jtyberg /var/lib/docker/volumes/jtyberg/_data /home/jovyan/work local rw true rprivate}] + [{jtyberg /var/lib/docker/volumes/jtyberg/_data /home/jovyan/work local rw true rprivate}] ``` We can backup the user's notebook directory by running a separate container that mounts the user's volume and creates a tarball of the directory. -``` +```bash docker run --rm \ -u root \ -v /tmp:/backups \ diff --git a/docs/oauth-form.png b/docs/oauth-form.png new file mode 100644 index 0000000..8d0f1cc Binary files /dev/null and b/docs/oauth-form.png differ