repo2docker/docs/source/use/extend-community-image.md

3.6 KiB

Extend a community image with your own packages

If using a community image alone doesn't provide the environment you need, you might get away with just installing one or two extra things on top of it.

To do this, you should define a Dockerfile that "inherits" the community image, and "extend" it to add a few extra things.

Here's a repository that demonstrates how to do this using the repo2docker github action. Below is a summary of the most important parts.

A local environment.yml file defines only the extra things to install in addition to the upstream image.

:caption: environment.yml
channels:
  - conda-forge

dependencies:
  - jupyterhub-singleuser>=3.0,<4.0

  # Everyone wants to use nbgitpuller for everything, so let's do that
  - nbgitpuller=1.1.*
  # Install packages from pip
  - pip
  - pip:
    - otter-grader

A local Dockerfile does the following things:

  • Inherits from the upstream image.
  • Copies your local environment.yml file into a directory in the image.
  • Updates the conda environment with it to install the extra packages.

For example, the following inherits the scipy-notebook image with the 2023-05-01 tag and takes the above steps. (you could follow a similar workflow with other package managers).

:caption: Dockerfile
FROM jupyter/scipy-notebook:2023-05-01
COPY environment.yml /tmp/environment.yml
RUN mamba env update --prefix ${CONDA_DIR} --file /tmp/environment.yml
COPY image-tests image-tests
RUN ls

A github workflow uses the repo2docker GitHub action to build and push a Docker image using repo2docker. Here's an example of what the GitHub workflow looks like:

```{code-block} yaml
:caption: .github/workflows/build.yaml
name: Build and push container image

on:
  push:
    branches:
      - main

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:

    # For biggish images, github actions runs out of disk space.
    # So we cleanup some unwanted things in the disk image, and reclaim that space for our Docker use
    # https://github.com/actions/virtual-environments/issues/2606#issuecomment-772683150
    # and https://github.com/easimon/maximize-build-space/blob/b4d02c14493a9653fe7af06cc89ca5298071c66e/action.yml#L104
    # This gives us a total of about 52G of free space, which should be enough for now
    - name: cleanup disk space
      run: |
        sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc
        df -h

    - name: Checkout files in repo
      uses: actions/checkout@main

    - name: Build and push the image to quay.io
      uses: jupyterhub/repo2docker-action@master
      with:
        # Make sure username & password/token pair matches your registry credentials
        DOCKER_USERNAME: ${{ secrets.QUAY_USERNAME }}
        DOCKER_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
        DOCKER_REGISTRY: "quay.io"
        # Disable pushing a 'latest' tag, as this often just causes confusion
        LATEST_TAG_OFF: true
        #
        # Uncomment and modify the following line with your image name, otherwise no push will happen
        IMAGE_NAME: "yuvipanda/example-inherit-from-community-image"

    # Lets us monitor disks getting full as images get bigger over time
    - name: Show how much disk space is left
      run: df -h
```