diff --git a/.github/workflows/jupyterhub-base-cuda12.2-cudnn8-py3.9.yml b/.github/workflows/jupyterhub-base-cuda12.2-cudnn8-py3.9.yml new file mode 100644 index 0000000..15e2577 --- /dev/null +++ b/.github/workflows/jupyterhub-base-cuda12.2-cudnn8-py3.9.yml @@ -0,0 +1,22 @@ +on: + push: + paths: + - jupyterhub/base-cuda12.2-cudnn8-py3.9/**/* + - .github/workflows/jupyterhub-base-cuda12.2-cudnn8-py3.9.yml + - .github/workflows/builder.yml + branches: + - "master" + - "main" + - "latest" + release: + types: + - created +jobs: + build-jupyterhub-base-cuda122-cudnn8-py311: + uses: ./.github/workflows/builder.yml + with: + context: jupyterhub/base-cuda12.2-cudnn8-py3.9 + dockerfile: jupyterhub/base-cuda12.2-cudnn8-py3.9/Dockerfile + name: ertis-research/jupyterhub-base-cuda12.2-cudnn8-py3.9 + platforms: linux/amd64 + diff --git a/.github/workflows/jupyterhub-base-py3.9.yml b/.github/workflows/jupyterhub-base-py3.9.yml new file mode 100644 index 0000000..b53bf34 --- /dev/null +++ b/.github/workflows/jupyterhub-base-py3.9.yml @@ -0,0 +1,22 @@ +on: + push: + paths: + - jupyterhub/base-py3.9/**/* + - .github/workflows/jupyterhub-base-py3.9.yml + - .github/workflows/builder.yml + branches: + - "master" + - "main" + - "latest" + release: + types: + - created +jobs: + build-jupyterhub-base-py311: + uses: ./.github/workflows/builder.yml + with: + context: jupyterhub/base-py3.9 + dockerfile: jupyterhub/base-py3.9/Dockerfile + name: ertis-research/jupyterhub-base-py3.9 + platforms: linux/amd64 + diff --git a/.github/workflows/jupyterhub-pth-cuda12.2-cudnn8-py3.9.yml b/.github/workflows/jupyterhub-pth-cuda12.2-cudnn8-py3.9.yml new file mode 100644 index 0000000..bdc784d --- /dev/null +++ b/.github/workflows/jupyterhub-pth-cuda12.2-cudnn8-py3.9.yml @@ -0,0 +1,22 @@ +on: + push: + paths: + - jupyterhub/pth-cuda12.2-cudnn8-py3.9/**/* + - .github/workflows/jupyterhub-pth-cuda12.2-cudnn8-py3.9.yml + - .github/workflows/builder.yml + branches: + - "master" + - "main" + - "latest" + release: + types: + - created +jobs: + build-jupyterhub-pth-cuda122-cudnn8-py311: + uses: ./.github/workflows/builder.yml + with: + context: jupyterhub/pth-cuda12.2-cudnn8-py3.9 + dockerfile: jupyterhub/pth-cuda12.2-cudnn8-py3.9/Dockerfile + name: ertis-research/jupyterhub-pth-cuda12.2-cudnn8-py3.9 + platforms: linux/amd64 + diff --git a/.github/workflows/jupyterhub-tf-cuda12.2-cudnn8-py3.9.yml b/.github/workflows/jupyterhub-tf-cuda12.2-cudnn8-py3.9.yml new file mode 100644 index 0000000..5d58da0 --- /dev/null +++ b/.github/workflows/jupyterhub-tf-cuda12.2-cudnn8-py3.9.yml @@ -0,0 +1,22 @@ +on: + push: + paths: + - jupyterhub/tf-cuda12.2-cudnn8-py3.9/**/* + - .github/workflows/jupyterhub-tf-cuda12.2-cudnn8-py3.9.yml + - .github/workflows/builder.yml + branches: + - "master" + - "main" + - "latest" + release: + types: + - created +jobs: + build-jupyterhub-tf-cuda122-cudnn8-py311: + uses: ./.github/workflows/builder.yml + with: + context: jupyterhub/tf-cuda12.2-cudnn8-py3.9 + dockerfile: jupyterhub/tf-cuda12.2-cudnn8-py3.9/Dockerfile + name: ertis-research/jupyterhub-tf-cuda12.2-cudnn8-py3.9 + platforms: linux/amd64 + diff --git a/jupyterhub/base-cuda12.2-cudnn8-py3.11/Dockerfile b/jupyterhub/base-cuda12.2-cudnn8-py3.11/Dockerfile index 8a3d245..ca5a05a 100644 --- a/jupyterhub/base-cuda12.2-cudnn8-py3.11/Dockerfile +++ b/jupyterhub/base-cuda12.2-cudnn8-py3.11/Dockerfile @@ -6,7 +6,7 @@ ARG DEBIAN_FRONTEND=noninteractive USER root -# Install some basic utilities and python3.10 +# Install some basic utilities and python3.11 RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ ca-certificates \ @@ -28,7 +28,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ dnsutils \ zip \ unzip \ - python3.10-venv \ + python3.11-venv \ htop \ atop \ jq \ @@ -49,7 +49,7 @@ RUN mkdir -p /etc/apt/keyrings && \ && \ apt-get clean && rm -rf /var/lib/apt/lists/* -# Install Python 3.10 +# Install Python 3.11 RUN apt-get update --yes && \ apt-get install --yes --no-install-recommends \ python3.11 \ diff --git a/jupyterhub/base-cuda12.2-cudnn8-py3.9/Dockerfile b/jupyterhub/base-cuda12.2-cudnn8-py3.9/Dockerfile new file mode 100644 index 0000000..b053568 --- /dev/null +++ b/jupyterhub/base-cuda12.2-cudnn8-py3.9/Dockerfile @@ -0,0 +1,118 @@ +# syntax=docker/dockerfile:1.3-labs + +FROM nvidia/cuda:12.2.2-cudnn8-devel-ubuntu22.04 + +ARG DEBIAN_FRONTEND=noninteractive + +USER root + +# Install some basic utilities and python3.9 +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + sudo \ + git \ + bzip2 \ + tzdata \ + less \ + xclip \ + libx11-6 \ + nano \ + bat \ + locales \ + sudo \ + iputils-ping \ + gpg \ + tini \ + wget \ + dnsutils \ + zip \ + unzip \ + python3.9-venv \ + htop \ + atop \ + jq \ + zsh \ + sed \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* && \ + echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ + locale-gen + +# Install EZA +RUN mkdir -p /etc/apt/keyrings && \ + wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | sudo tee /etc/apt/sources.list.d/gierens.list && \ + chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list && \ + apt update -y && \ + apt install -y eza \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install Python 3.9 +RUN apt-get update --yes && \ + apt-get install --yes --no-install-recommends \ + python3.9 \ + python3-pip \ + python3.9-dev \ + python3.9-distutils \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +COPY jupyter_requirements.txt /tmp/jupyter_requirements.txt + +RUN pip install --no-cache-dir -r /tmp/jupyter_requirements.txt + +# Initialization of user copied from: +# https://github.com/jupyter/docker-stacks/blob/main/docker-stacks-foundation/Dockerfile + +ARG NB_USER="ertis" +ARG NB_UID="1000" +ARG NB_GID="100" + +# Fix: https://github.com/hadolint/hadolint/wiki/DL4006 +# Fix: https://github.com/koalaman/shellcheck/wiki/SC3014 +SHELL ["/bin/zsh", "-o", "pipefail", "-c"] + +USER root + +COPY fix-permissions /usr/local/bin/fix-permissions +RUN chmod a+rx /usr/local/bin/fix-permissions + +ENV HOME="/home/${NB_USER}" + +# Enable prompt color in the skeleton .bashrc before creating the default NB_USER +# hadolint ignore=SC2016 +RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc + +# Create NB_USER with name jovyan user with UID=1000 and in the 'users' group +# and make sure these dirs are writable by the `users` group. +RUN echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \ + useradd -l -m -s /bin/bash -N -u "${NB_UID}" "${NB_USER}" && \ + chmod g+w /etc/passwd && \ + fix-permissions "${HOME}" + +# RUN chsh -s /bin/zsh + +RUN sed -i 's/auth\s*sufficient\s*pam_shells.so/auth\s*required\s*pam_shells.so/g' /etc/pam.d/chsh +# Additional line to modify pam_rootok.so (usually not needed) +# RUN sed -i 's/auth\s*sufficient\s*pam_rootok.so/auth\s*required\s*pam_rootok.so/g' /etc/pam.d/chsh + +USER ${NB_UID} + +RUN chsh -s /bin/zsh + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN <> ~/.bashrc + echo "alias cat='batcat'" >> ~/.bashrc +EOF + + +RUN <> ~/.zshrc + echo "alias cat='batcat'" >> ~/.zshrc +EOF + +WORKDIR "${HOME}" diff --git a/jupyterhub/base-cuda12.2-cudnn8-py3.9/README.md b/jupyterhub/base-cuda12.2-cudnn8-py3.9/README.md new file mode 100644 index 0000000..fd756bc --- /dev/null +++ b/jupyterhub/base-cuda12.2-cudnn8-py3.9/README.md @@ -0,0 +1,8 @@ +# Base GPU Jupyter notebook image for Jupyter hub + +Based on the [Jupyter Docker Stacks](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html) project and [Zonca's JupyterHub JetStream Deploy](https://github.com/zonca/jupyterhub-deploy-kubernetes-jetstream/blob/master/gpu/nvidia-tensorflow-jupyterhub/fix-permissions) + +Please visit the project documentation site for help to use and contribute to this image and others. + +- [Jupyter Docker Stacks on ReadTheDocs](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html) +- [Selecting an Image :: Core Stacks :: jupyter/docker-stacks-foundation](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html#jupyter-docker-stacks-foundation) diff --git a/jupyterhub/base-cuda12.2-cudnn8-py3.9/fix-permissions b/jupyterhub/base-cuda12.2-cudnn8-py3.9/fix-permissions new file mode 100644 index 0000000..d167578 --- /dev/null +++ b/jupyterhub/base-cuda12.2-cudnn8-py3.9/fix-permissions @@ -0,0 +1,35 @@ +#!/bin/bash +# set permissions on a directory +# after any installation, if a directory needs to be (human) user-writable, +# run this script on it. +# It will make everything in the directory owned by the group ${NB_GID} +# and writable by that group. +# Deployments that want to set a specific user id can preserve permissions +# by adding the `--group-add users` line to `docker run`. + +# uses find to avoid touching files that already have the right permissions, +# which would cause massive image explosion + +# right permissions are: +# group=${NB_GID} +# AND permissions include group rwX (directory-execute) +# AND directories have setuid,setgid bits set + +set -e + +for d in "$@"; do + find "${d}" \ + ! \( \ + -group "${NB_GID}" \ + -a -perm -g+rwX \ + \) \ + -exec chgrp "${NB_GID}" -- {} \+ \ + -exec chmod g+rwX -- {} \+ + # setuid, setgid *on directories only* + find "${d}" \ + \( \ + -type d \ + -a ! -perm -6000 \ + \) \ + -exec chmod +6000 -- {} \+ +done diff --git a/jupyterhub/base-cuda12.2-cudnn8-py3.9/jupyter_requirements.txt b/jupyterhub/base-cuda12.2-cudnn8-py3.9/jupyter_requirements.txt new file mode 100644 index 0000000..89035a4 --- /dev/null +++ b/jupyterhub/base-cuda12.2-cudnn8-py3.9/jupyter_requirements.txt @@ -0,0 +1,4 @@ +jupyterhub==4.0.2 +jupyterlab==4.0.8 +notebook==7.0.6 +jupyter_server==2.10.1 \ No newline at end of file diff --git a/jupyterhub/base-py3.11/Dockerfile b/jupyterhub/base-py3.11/Dockerfile index cb8167f..a022086 100644 --- a/jupyterhub/base-py3.11/Dockerfile +++ b/jupyterhub/base-py3.11/Dockerfile @@ -94,14 +94,10 @@ RUN echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \ # RUN chsh -s /bin/zsh -RUN sed -i 's/auth\s*sufficient\s*pam_shells.so/auth\s*required\s*pam_shells.so/g' /etc/pam.d/chsh -# Additional line to modify pam_rootok.so (usually not needed) -# RUN sed -i 's/auth\s*sufficient\s*pam_rootok.so/auth\s*required\s*pam_rootok.so/g' /etc/pam.d/chsh +RUN chsh -s /bin/zsh ${NB_UID} USER ${NB_UID} -RUN chsh -s /bin/zsh - SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN < /etc/locale.gen && \ + locale-gen + +# Install EZA +RUN mkdir -p /etc/apt/keyrings && \ + wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | sudo tee /etc/apt/sources.list.d/gierens.list && \ + chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list && \ + apt update -y && \ + apt install -y eza \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install Python 3.9 +RUN apt-get update --yes && \ + apt-get install --yes --no-install-recommends \ + python3.9 \ + python3-pip \ + python3.9-dev \ + python3.9-distutils \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +COPY jupyter_requirements.txt /tmp/jupyter_requirements.txt + +RUN pip install --no-cache-dir -r /tmp/jupyter_requirements.txt + +# Initialization of user copied from: +# https://github.com/jupyter/docker-stacks/blob/main/docker-stacks-foundation/Dockerfile + +ARG NB_USER="ertis" +ARG NB_UID="1000" +ARG NB_GID="100" + +# Fix: https://github.com/hadolint/hadolint/wiki/DL4006 +# Fix: https://github.com/koalaman/shellcheck/wiki/SC3014 +SHELL ["/bin/zsh", "-o", "pipefail", "-c"] + +USER root + +COPY fix-permissions /usr/local/bin/fix-permissions +RUN chmod a+rx /usr/local/bin/fix-permissions + +ENV HOME="/home/${NB_USER}" + +# Enable prompt color in the skeleton .bashrc before creating the default NB_USER +# hadolint ignore=SC2016 +RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc + +# Create NB_USER with name jovyan user with UID=1000 and in the 'users' group +# and make sure these dirs are writable by the `users` group. +RUN echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \ + useradd -l -m -s /bin/bash -N -u "${NB_UID}" "${NB_USER}" && \ + chmod g+w /etc/passwd && \ + fix-permissions "${HOME}" + +# RUN chsh -s /bin/zsh + +RUN chsh -s /bin/zsh ${NB_UID} + +USER ${NB_UID} + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN <> ~/.bashrc + echo "alias cat='batcat'" >> ~/.bashrc +EOF + +RUN <> ~/.zshrc + echo "alias cat='batcat'" >> ~/.zshrc +EOF + +WORKDIR "${HOME}" diff --git a/jupyterhub/tensorflow-gpu/README.md b/jupyterhub/base-py3.9/README.md similarity index 90% rename from jupyterhub/tensorflow-gpu/README.md rename to jupyterhub/base-py3.9/README.md index bd2fc83..61ce528 100644 --- a/jupyterhub/tensorflow-gpu/README.md +++ b/jupyterhub/base-py3.9/README.md @@ -1,4 +1,4 @@ -# TensorFlow Jupyter notebook image for Jupyter hub +# Base CPU Jupyter notebook image for Jupyter hub Based on the [Jupyter Docker Stacks](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html) project. diff --git a/jupyterhub/base-py3.9/fix-permissions b/jupyterhub/base-py3.9/fix-permissions new file mode 100644 index 0000000..d167578 --- /dev/null +++ b/jupyterhub/base-py3.9/fix-permissions @@ -0,0 +1,35 @@ +#!/bin/bash +# set permissions on a directory +# after any installation, if a directory needs to be (human) user-writable, +# run this script on it. +# It will make everything in the directory owned by the group ${NB_GID} +# and writable by that group. +# Deployments that want to set a specific user id can preserve permissions +# by adding the `--group-add users` line to `docker run`. + +# uses find to avoid touching files that already have the right permissions, +# which would cause massive image explosion + +# right permissions are: +# group=${NB_GID} +# AND permissions include group rwX (directory-execute) +# AND directories have setuid,setgid bits set + +set -e + +for d in "$@"; do + find "${d}" \ + ! \( \ + -group "${NB_GID}" \ + -a -perm -g+rwX \ + \) \ + -exec chgrp "${NB_GID}" -- {} \+ \ + -exec chmod g+rwX -- {} \+ + # setuid, setgid *on directories only* + find "${d}" \ + \( \ + -type d \ + -a ! -perm -6000 \ + \) \ + -exec chmod +6000 -- {} \+ +done diff --git a/jupyterhub/base-py3.9/jupyter_requirements.txt b/jupyterhub/base-py3.9/jupyter_requirements.txt new file mode 100644 index 0000000..89035a4 --- /dev/null +++ b/jupyterhub/base-py3.9/jupyter_requirements.txt @@ -0,0 +1,4 @@ +jupyterhub==4.0.2 +jupyterlab==4.0.8 +notebook==7.0.6 +jupyter_server==2.10.1 \ No newline at end of file diff --git a/jupyterhub/pth-cuda12.2-cudnn8-py3.9/Dockerfile b/jupyterhub/pth-cuda12.2-cudnn8-py3.9/Dockerfile new file mode 100644 index 0000000..58df1ee --- /dev/null +++ b/jupyterhub/pth-cuda12.2-cudnn8-py3.9/Dockerfile @@ -0,0 +1,30 @@ +# syntax=docker/dockerfile:1.3-labs + +FROM ghcr.io/ertis-research/jupyterhub-base-cuda12.2-cudnn8-py3.9:main + +ARG DEBIAN_FRONTEND=noninteractive + +USER root + +COPY requirements.txt /tmp/requirements.txt + +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +ARG NB_USER="ertis" + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +ENV HOME="/home/${NB_USER}" + +RUN chsh -s /bin/bash + +USER ${NB_UID} + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN <> ~/.bashrc + echo "alias cat='batcat'" >> ~/.bashrc +EOF + +WORKDIR "${HOME}" \ No newline at end of file diff --git a/jupyterhub/pth-cuda12.2-cudnn8-py3.9/README.md b/jupyterhub/pth-cuda12.2-cudnn8-py3.9/README.md new file mode 100644 index 0000000..fd756bc --- /dev/null +++ b/jupyterhub/pth-cuda12.2-cudnn8-py3.9/README.md @@ -0,0 +1,8 @@ +# Base GPU Jupyter notebook image for Jupyter hub + +Based on the [Jupyter Docker Stacks](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html) project and [Zonca's JupyterHub JetStream Deploy](https://github.com/zonca/jupyterhub-deploy-kubernetes-jetstream/blob/master/gpu/nvidia-tensorflow-jupyterhub/fix-permissions) + +Please visit the project documentation site for help to use and contribute to this image and others. + +- [Jupyter Docker Stacks on ReadTheDocs](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html) +- [Selecting an Image :: Core Stacks :: jupyter/docker-stacks-foundation](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html#jupyter-docker-stacks-foundation) diff --git a/jupyterhub/pth-cuda12.2-cudnn8-py3.9/requirements.txt b/jupyterhub/pth-cuda12.2-cudnn8-py3.9/requirements.txt new file mode 100644 index 0000000..88197b1 --- /dev/null +++ b/jupyterhub/pth-cuda12.2-cudnn8-py3.9/requirements.txt @@ -0,0 +1,12 @@ +numpy==1.26.2 +scipy==1.11.4 +matplotlib==3.8.2 +Pillow==10.1.0 +scikit-learn==1.3.2 +pandas==2.1.3 +plotly==5.18.0 +requests==2.31.0 +opencv-python==4.8.1.78 +torch==2.1.1 +torchvision==0.16.1 +torchaudio==2.1.1 \ No newline at end of file diff --git a/jupyterhub/tensorflow-gpu/Dockerfile b/jupyterhub/tensorflow-gpu/Dockerfile deleted file mode 100644 index a6147e6..0000000 --- a/jupyterhub/tensorflow-gpu/Dockerfile +++ /dev/null @@ -1,163 +0,0 @@ -# Base image: https://github.com/jupyter/docker-stacks/blob/74bbd0bffc3b444e2d65279739bc2d681b6199e2/images/docker-stacks-foundation/Dockerfile - -# ARG ROOT_CONTAINER=tensorflow/tensorflow:2.15.0-gpu -# ARG ROOT_CONTAINER=pytorch/pytorch:2.1.1-cuda12.1-cudnn8-runtime -# ARG ROOT_CONTAINER=ubuntu:22.04 -ARG ROOT_CONTAINER=nvidia/cuda:12.2.2-cudnn8-runtime-ubuntu22.04 - -ARG FOUNDATION_CONTAINER=quay.io/jupyter/docker-stacks-foundation:4d70cf8da953 -ARG BASE_NOTEBOOK=quay.io/jupyter/base-notebook:b86753318aa1 -ARG MIN_NOTEBOOK - - -FROM ${FOUNDATION_CONTAINER} as foundation -FROM ${BASE_NOTEBOOK} as base_notebook - -FROM $ROOT_CONTAINER - -LABEL maintainer="Antonio J. Chaves " - -ARG NB_USER="ertis" -ARG NB_UID="1000" -ARG NB_GID="100" - -# Pin python version here, or set it to "default" -ARG PYTHON_VERSION=3.11 - - -ENV DEBIAN_FRONTEND noninteractive - -# Configure environment -ENV SHELL=/bin/bash \ - NB_USER="${NB_USER}" \ - NB_UID=${NB_UID} \ - NB_GID=${NB_GID} \ - LC_ALL=en_US.UTF-8 \ - LANG=en_US.UTF-8 \ - LANGUAGE=en_US.UTF-8 \ - PATH="${PATH}:/home/${NB_USER}/.local/bin" - - -ENV HOME="/home/${NB_USER}" - -ENV JUPYTER_PORT=8888 - - -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -USER root - -COPY --from=foundation /usr/local/bin/fix-permissions /usr/local/bin/ -COPY --from=foundation /usr/local/bin/start.sh /usr/local/bin/ -COPY run-hooks.sh /usr/local/bin/run-hooks.sh - -COPY --from=base_notebook /usr/local/bin/start-notebook.sh /usr/local/bin/ -COPY --from=base_notebook /usr/local/bin/start-singleuser.sh /usr/local/bin/ -COPY start-notebook.py start-singleuser.py /usr/local/bin/ -# COPY --from=base_notebook /etc/jupyter/jupyter_server_config.py /etc/jupyter/ -# COPY --from=base_notebook /etc/jupyter/docker_healthcheck.py /etc/jupyter/ -COPY jupyter_server_config.py /etc/jupyter/jupyter_server_config.py -COPY docker_healthcheck.py /etc/jupyter/docker_healthcheck.py - - -RUN apt-get update --yes && \ - apt-get upgrade --yes && \ - apt-get install --yes --no-install-recommends \ - bzip2 \ - curl \ - git \ - tzdata \ - openssh-client \ - less \ - xclip \ - git \ - nano \ - bat \ - run-one \ - iputils-ping \ - ca-certificates \ - locales \ - sudo \ - gpg \ - tini \ - wget && \ - apt-get clean && rm -rf /var/lib/apt/lists/* && \ - echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ - locale-gen - - -RUN mkdir -p /etc/apt/keyrings && \ - wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg && \ - echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | sudo tee /etc/apt/sources.list.d/gierens.list && \ - chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list && \ - apt update -y && \ - apt install -y eza \ - texlive-xetex \ - texlive-fonts-recommended \ - texlive-plain-generic \ - fonts-liberation \ - pandoc \ - python3-pip && \ - apt-get clean && rm -rf /var/lib/apt/lists/* - -# Copy a script that we will use to correct permissions after running certain commands -RUN chmod a+rx /usr/local/bin/fix-permissions - -RUN echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \ - sed -i.bak -e 's/^%admin/#%admin/' /etc/sudoers && \ - sed -i.bak -e 's/^%sudo/#%sudo/' /etc/sudoers && \ - useradd --no-log-init --create-home --shell /bin/bash --uid "${NB_UID}" --no-user-group "${NB_USER}" && \ - chmod g+w /etc/passwd && \ - fix-permissions "/home/${NB_USER}" - -USER ${NB_UID} - -# Setup work directory for backward-compatibility -RUN mkdir "/home/${NB_USER}/work" && \ - fix-permissions "/home/${NB_USER}" - -WORKDIR /tmp - -RUN pip install jupyter-core \ - jupyterlab \ - notebook \ - jupyterhub \ - nbclassic \ - tensorflow && \ - jupyter server --generate-config && \ - jupyter lab clean && \ - rm -rf "/home/${NB_USER}/.cache/yarn" && \ - fix-permissions "/home/${NB_USER}" - -# Configure container startup -ENTRYPOINT ["tini", "-g", "--"] - -USER root - -# Create dirs for startup hooks -RUN mkdir /usr/local/bin/start-notebook.d && \ - mkdir /usr/local/bin/before-notebook.d - -USER ${NB_UID} - - -EXPOSE $JUPYTER_PORT - -# Configure container startup -CMD ["start-notebook.py"] - -# Fix permissions on /etc/jupyter as root -USER root -RUN fix-permissions /etc/jupyter/ && \ - fix-permissions "/home/${NB_USER}" - -# HEALTHCHECK documentation: https://docs.docker.com/engine/reference/builder/#healthcheck -# This healtcheck works well for `lab`, `notebook`, `nbclassic`, `server` and `retro` jupyter commands -# https://github.com/jupyter/docker-stacks/issues/915#issuecomment-1068528799 -HEALTHCHECK --interval=5s --timeout=3s --start-period=5s --retries=3 \ - CMD /etc/jupyter/docker_healthcheck.py || exit 1 - -# Switch back to jovyan to avoid accidental container runs as root -USER ${NB_UID} - -WORKDIR "${HOME}" \ No newline at end of file diff --git a/jupyterhub/tensorflow-gpu/docker_healthcheck.py b/jupyterhub/tensorflow-gpu/docker_healthcheck.py deleted file mode 100644 index 41bbc78..0000000 --- a/jupyterhub/tensorflow-gpu/docker_healthcheck.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -import json -import os -from pathlib import Path - -import requests - -# A number of operations below deliberately don't check for possible errors -# As this is a healthcheck, it should succeed or raise an exception on error - -runtime_dir = Path("/home/") / os.environ["NB_USER"] / ".local/share/jupyter/runtime/" -json_file = next(runtime_dir.glob("*server-*.json")) - -url = json.loads(json_file.read_bytes())["url"] -url = url + "api" - -proxies = { - "http": "", - "https": "", -} - -r = requests.get(url, proxies=proxies, verify=False) # request without SSL verification -r.raise_for_status() -print(r.content) diff --git a/jupyterhub/tensorflow-gpu/jupyter_server_config.py b/jupyterhub/tensorflow-gpu/jupyter_server_config.py deleted file mode 100644 index 5c13308..0000000 --- a/jupyterhub/tensorflow-gpu/jupyter_server_config.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -# mypy: ignore-errors -import os -import stat -import subprocess -from pathlib import Path - -from jupyter_core.paths import jupyter_data_dir - -c = get_config() # noqa: F821 -c.ServerApp.ip = "0.0.0.0" -c.ServerApp.open_browser = False - -# to output both image/svg+xml and application/pdf plot formats in the notebook file -c.InlineBackend.figure_formats = {"png", "jpeg", "svg", "pdf"} - -# https://github.com/jupyter/notebook/issues/3130 -c.FileContentsManager.delete_to_trash = False - -# Generate a self-signed certificate -OPENSSL_CONFIG = """\ -[req] -distinguished_name = req_distinguished_name -[req_distinguished_name] -""" -if "GEN_CERT" in os.environ: - dir_name = Path(jupyter_data_dir()) - dir_name.mkdir(parents=True, exist_ok=True) - pem_file = dir_name / "notebook.pem" - - # Generate an openssl.cnf file to set the distinguished name - cnf_file = Path(os.getenv("CONDA_DIR", "/usr/lib")) / "ssl/openssl.cnf" - if not cnf_file.exists(): - cnf_file.write_text(OPENSSL_CONFIG) - - # 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", - f"-keyout={pem_file}", - f"-out={pem_file}", - ] - ) - # Restrict access to the file - pem_file.chmod(stat.S_IRUSR | stat.S_IWUSR) - c.ServerApp.certfile = str(pem_file) - -# Change default umask for all subprocesses of the Server if set in the environment -if "NB_UMASK" in os.environ: - os.umask(int(os.environ["NB_UMASK"], 8)) diff --git a/jupyterhub/tensorflow-gpu/run-hooks.sh b/jupyterhub/tensorflow-gpu/run-hooks.sh deleted file mode 100644 index d5dc28e..0000000 --- a/jupyterhub/tensorflow-gpu/run-hooks.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -# The run-hooks.sh script looks for *.sh scripts to source -# and executable files to run within a passed directory - -if [ "$#" -ne 1 ]; then - echo "Should pass exactly one directory" - return 1 -fi - -if [[ ! -d "${1}" ]] ; then - echo "Directory ${1} doesn't exist or is not a directory" - return 1 -fi - -echo "Running hooks in: ${1} as uid: $(id -u) gid: $(id -g)" -for f in "${1}/"*; do - # Hadling a case when the directory is empty - [ -e "${f}" ] || continue - case "${f}" in - *.sh) - echo "Sourcing shell script: ${f}" - # shellcheck disable=SC1090 - source "${f}" - # shellcheck disable=SC2181 - if [ $? -ne 0 ] ; then - echo "${f} has failed, continuing execution" - fi - ;; - *) - if [ -x "${f}" ] ; then - echo "Running executable: ${f}" - "${f}" - # shellcheck disable=SC2181 - if [ $? -ne 0 ] ; then - echo "${f} has failed, continuing execution" - fi - else - echo "Ignoring non-executable: ${f}" - fi - ;; - esac -done -echo "Done running hooks in: ${1}" diff --git a/jupyterhub/tensorflow-gpu/start-notebook.py b/jupyterhub/tensorflow-gpu/start-notebook.py deleted file mode 100644 index db1efc2..0000000 --- a/jupyterhub/tensorflow-gpu/start-notebook.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -import os -import shlex -import sys - -# If we are in a JupyterHub, we pass on to `start-singleuser.py` instead so it does the right thing -if "JUPYTERHUB_API_TOKEN" in os.environ: - print( - "WARNING: using start-singleuser.py instead of start-notebook.py to start a server associated with JupyterHub." - ) - command = ["/usr/local/bin/start-singleuser.py"] + sys.argv[1:] - os.execvp(command[0], command) - - -# Wrap everything in start.sh, no matter what -command = ["/usr/local/bin/start.sh"] - -# If we want to survive restarts, tell that to start.sh -if os.environ.get("RESTARTABLE") == "yes": - command.append("run-one-constantly") - -# We always launch a jupyter subcommand from this script -command.append("jupyter") - -# Launch the configured subcommand. Note that this should be a single string, so we don't split it -# We default to lab -jupyter_command = os.environ.get("DOCKER_STACKS_JUPYTER_CMD", "lab") -command.append(jupyter_command) - -# Append any optional NOTEBOOK_ARGS we were passed in. This is supposed to be multiple args passed -# on to the notebook command, so we split it correctly with shlex -if "NOTEBOOK_ARGS" in os.environ: - command += shlex.split(os.environ["NOTEBOOK_ARGS"]) - -# Pass through any other args we were passed on the commandline -command += sys.argv[1:] - -# Execute the command! -os.execvp(command[0], command) diff --git a/jupyterhub/tensorflow-gpu/start-singleuser.py b/jupyterhub/tensorflow-gpu/start-singleuser.py deleted file mode 100644 index 2dcf6c0..0000000 --- a/jupyterhub/tensorflow-gpu/start-singleuser.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. -import os -import shlex -import sys - -command = ["/usr/local/bin/start.sh", "jupyterhub-singleuser"] - -# set default ip to 0.0.0.0 -if "--ip=" not in os.environ.get("NOTEBOOK_ARGS", ""): - command.append("--ip=0.0.0.0") - -# Append any optional NOTEBOOK_ARGS we were passed in. This is supposed to be multiple args passed -# on to the notebook command, so we split it correctly with shlex -if "NOTEBOOK_ARGS" in os.environ: - command += shlex.split(os.environ["NOTEBOOK_ARGS"]) - -# Pass any other args we have been passed through -command += sys.argv[1:] - -# Execute the command! -os.execvp(command[0], command) diff --git a/jupyterhub/tf-cuda12.2-cudnn8-py3.9/Dockerfile b/jupyterhub/tf-cuda12.2-cudnn8-py3.9/Dockerfile new file mode 100644 index 0000000..58df1ee --- /dev/null +++ b/jupyterhub/tf-cuda12.2-cudnn8-py3.9/Dockerfile @@ -0,0 +1,30 @@ +# syntax=docker/dockerfile:1.3-labs + +FROM ghcr.io/ertis-research/jupyterhub-base-cuda12.2-cudnn8-py3.9:main + +ARG DEBIAN_FRONTEND=noninteractive + +USER root + +COPY requirements.txt /tmp/requirements.txt + +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +ARG NB_USER="ertis" + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +ENV HOME="/home/${NB_USER}" + +RUN chsh -s /bin/bash + +USER ${NB_UID} + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN <> ~/.bashrc + echo "alias cat='batcat'" >> ~/.bashrc +EOF + +WORKDIR "${HOME}" \ No newline at end of file diff --git a/jupyterhub/tf-cuda12.2-cudnn8-py3.9/README.md b/jupyterhub/tf-cuda12.2-cudnn8-py3.9/README.md new file mode 100644 index 0000000..fd756bc --- /dev/null +++ b/jupyterhub/tf-cuda12.2-cudnn8-py3.9/README.md @@ -0,0 +1,8 @@ +# Base GPU Jupyter notebook image for Jupyter hub + +Based on the [Jupyter Docker Stacks](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html) project and [Zonca's JupyterHub JetStream Deploy](https://github.com/zonca/jupyterhub-deploy-kubernetes-jetstream/blob/master/gpu/nvidia-tensorflow-jupyterhub/fix-permissions) + +Please visit the project documentation site for help to use and contribute to this image and others. + +- [Jupyter Docker Stacks on ReadTheDocs](https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html) +- [Selecting an Image :: Core Stacks :: jupyter/docker-stacks-foundation](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html#jupyter-docker-stacks-foundation) diff --git a/jupyterhub/tf-cuda12.2-cudnn8-py3.9/requirements.txt b/jupyterhub/tf-cuda12.2-cudnn8-py3.9/requirements.txt new file mode 100644 index 0000000..dec818a --- /dev/null +++ b/jupyterhub/tf-cuda12.2-cudnn8-py3.9/requirements.txt @@ -0,0 +1,10 @@ +numpy==1.26.2 +scipy==1.11.4 +matplotlib==3.8.2 +Pillow==10.1.0 +scikit-learn==1.3.2 +pandas==2.1.3 +plotly==5.18.0 +requests==2.31.0 +opencv-python==4.8.1.78 +tensorflow==2.15.0