Running a Container#

Using one of the Jupyter Docker Stacks requires two choices:

  1. Which Docker image you wish to use

  2. How you wish to start Docker containers from that image

This section provides details about the second.

Using the Docker CLI#

You can launch a local Docker container from the Jupyter Docker Stacks using the Docker command-line interface. There are numerous ways to configure containers using the CLI. The following are some common patterns.

Example 1:

This command pulls the jupyter/scipy-notebook image tagged 85f615d5cafa from Docker Hub if it is not already present on the local host. It then starts a container running a Jupyter Notebook server and exposes the server on host port 8888. The server logs appear in the terminal and include a URL to the notebook server.

docker run -it -p 8888:8888 jupyter/scipy-notebook:85f615d5cafa

# Entered start.sh with args: jupyter lab

# ...

#     To access the server, open this file in a browser:
#         file:///home/jovyan/.local/share/jupyter/runtime/jpserver-7-open.html
#     Or copy and paste one of these URLs:
#         http://042fc8ac2b0c:8888/lab?token=f31f2625f13d131f578fced0fc76b81d10f6c629e92c7099
#      or http://127.0.0.1:8888/lab?token=f31f2625f13d131f578fced0fc76b81d10f6c629e92c7099

Pressing Ctrl-C twice shuts down the notebook server but leaves the container intact on disk for later restart or permanent deletion using commands like the following:

# list containers
docker ps -a
# CONTAINER ID   IMAGE                                                 COMMAND                  CREATED          STATUS                     PORTS     NAMES
# 221331c047c4   jupyter/scipy-notebook:85f615d5cafa                   "tini -g -- start-no…"   11 seconds ago   Exited (0) 8 seconds ago             cranky_benz

# start the stopped container
docker start -a 221331c047c4
# Entered start.sh with args: jupyter lab
# ...

# remove the stopped container
docker rm 221331c047c4
# 221331c047c4

Example 2:

This command pulls the jupyter/r-notebook image tagged 85f615d5cafa from Docker Hub if it is not already present on the local host. It then starts a container running a Jupyter Notebook server and exposes the server on host port 10000. The server logs appear in the terminal and include a URL to the notebook server, but with the internal container port (8888) instead of the correct host port (10000).

docker run -it --rm -p 10000:8888 -v "${PWD}":/home/jovyan/work jupyter/r-notebook:85f615d5cafa

Pressing Ctrl-C twice shuts down the notebook server and immediately destroys the Docker container. New files and changes in ~/work in the container will be preserved. Any other changes made in the container will be lost.

Example 3:

This command pulls the jupyter/all-spark-notebook image currently tagged latest from Docker Hub if an image tagged latest is not already present on the local host. It then starts a container named notebook running a JupyterLab server and exposes the server on a randomly selected port.

docker run -d -P --name notebook jupyter/all-spark-notebook

where:

  • -d: will run the container in detached mode

You can also use the following docker commands to see the port and notebook server token:

# get the random host port assigned to the container port 8888
docker port notebook 8888
# 0.0.0.0:49153
# :::49153

# get the notebook token from the logs
docker logs --tail 3 notebook
    # Or copy and paste one of these URLs:
    #     http://878f1a9b4dfa:8888/lab?token=d336fa63c03f064ff15ce7b269cab95b2095786cf9ab2ba3
    #  or http://127.0.0.1:8888/lab?token=d336fa63c03f064ff15ce7b269cab95b2095786cf9ab2ba3

Together, the URL to visit on the host machine to access the server, in this case, is http://127.0.0.1:49153/lab?token=d336fa63c03f064ff15ce7b269cab95b2095786cf9ab2ba3.

The container runs in the background until stopped and/or removed by additional Docker commands:

# stop the container
docker stop notebook
# notebook

# remove the container permanently
docker rm notebook
# notebook

Using the Podman CLI#

An alternative to using the Docker CLI is to use the Podman CLI. Podman is mostly compatible with Docker.

Example 4:

If we use Podman instead of Docker in the situation given in Example 2, it would look like this:

The example makes use of rootless Podman, in other words, the Podman command is run from a regular user account. In a Bash shell set the shell variables uid and gid to the UID and GID of the user jovyan in the container.

uid=1000
gid=100

Set the shell variables subuidSize and subgidSize to the number of subordinate UIDs and GIDs respectively.

subuidSize=$(( $(podman info --format "{{ range .Host.IDMappings.UIDMap }}+{{.Size }}{{end }}" ) - 1 ))
subgidSize=$(( $(podman info --format "{{ range .Host.IDMappings.GIDMap }}+{{.Size }}{{end }}" ) - 1 ))

This command pulls the docker.io/jupyter/r-notebook image tagged 85f615d5cafa from Docker Hub if it is not already present on the local host. It then starts a container running a Jupyter Server and exposes the server on host port 10000. The server logs appear in the terminal and include a URL to the notebook server, but with the internal container port (8888) instead of the correct host port (10000).

podman run -it --rm -p 10000:8888 \
    -v "${PWD}":/home/jovyan/work --user $uid:$gid \
    --uidmap $uid:0:1 --uidmap 0:1:$uid --uidmap $(($uid+1)):$(($uid+1)):$(($subuidSize-$uid)) \
    --gidmap $gid:0:1 --gidmap 0:1:$gid --gidmap $(($gid+1)):$(($gid+1)):$(($subgidSize-$gid)) \
    docker.io/jupyter/r-notebook:85f615d5cafa

Warning

The podman run options --uidmap and --gidmap can be used to map the container user jovyan to the regular user on the host when running rootless Podman. The same Podman command should not be run with sudo (i.e. running rootful Podman), because then the mapping would map the container user jovyan to the root user on the host. It’s a good security practice to run programs with as few privileges as possible.

Note

The podman run command in the example above maps all subuids and subgids of the user into the container. That works fine but is actually more than needed. The podman run option --userns=auto will, for instance, not be possible to use as long as there are no unused subuids and subgids available. The example could be improved by investigating more in detail which UIDs and GIDs need to be available in the container and then only map them.

Pressing Ctrl-C twice shuts down the notebook server and immediately destroys the Docker container. New files and changes in ~/work in the container will be preserved. Any other changes made in the container will be lost.

Using Binder#

Binder is a service that allows you to create and share custom computing environments for projects in version control. You can use any of the Jupyter Docker Stacks images as a basis for a Binder-compatible Dockerfile. See the docker-stacks example and Using a Dockerfile sections in the Binder documentation for instructions.

Using JupyterHub#

You can configure JupyterHub to launcher Docker containers from the Jupyter Docker Stacks images. If you’ve been following the Zero to JupyterHub with Kubernetes guide, see the Use an existing Docker image section for details. If you have a custom JupyterHub deployment, see the Picking or building a Docker image instructions for the dockerspawner instead.

Using Other Tools and Services#

You can use the Jupyter Docker Stacks with any Docker-compatible technology (e.g., Docker Compose, docker-py, your favorite cloud container service). See the documentation of the tool, library, or service for details about how to reference, configure, and launch containers from these images.