From ba0ca04e5651c55b809d589168e5fea2440b9734 Mon Sep 17 00:00:00 2001 From: Yuvi Panda Date: Wed, 28 Jun 2023 03:41:45 -0700 Subject: [PATCH] Add jupyter/julia-notebook (#1926) * Add jupyter/julia-notebook There is a growing number of Julia users in the Jupyter ecosystem who do not use R, and hence would <3 to have a dedicated docker image that doesn't bring in all the R stuff that datascience-notebook brings in! The built image size is much smaller, and eventually paves the way to better ecosystem support for Julia. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add a test for julia-notebook * Tell tests what julia-notebook inherits from * Sort lists with julia-notebook * Fix README for julia-notebook * Add julia-notebook to the makefile * Move julia-notebook below r-notebook * Use hard tabs in Makefile * Do some more sorting * Rename test_julia to avoid mypy issue * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Re-order julia/r-notebook Co-authored-by: Ayaz Salikhov * Move julia-notebook stanza under r-notebook * Update inheritance diagram --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ayaz Salikhov --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + .github/actions/download-manifests/action.yml | 10 +++ .github/workflows/docker.yml | 24 +++++++ .github/workflows/hub-overview.yml | 3 + Makefile | 1 + docs/images/inherit.svg | 7 ++ docs/using/selecting.md | 14 +++- julia-notebook/.dockerignore | 2 + julia-notebook/Dockerfile | 67 +++++++++++++++++++ julia-notebook/README.md | 12 ++++ tagging/images_hierarchy.py | 5 ++ tests/images_hierarchy.py | 1 + tests/julia-notebook/test_julia_exists.py | 18 +++++ 14 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 julia-notebook/.dockerignore create mode 100644 julia-notebook/Dockerfile create mode 100644 julia-notebook/README.md create mode 100644 tests/julia-notebook/test_julia_exists.py diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 9b8b24a235..3dc95c4f7f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -23,6 +23,7 @@ body: - all-spark-notebook - base-notebook - datascience-notebook + - julia-notebook - minimal-notebook - pyspark-notebook - r-notebook diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index e0d79587b9..89242a2bb3 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -21,6 +21,7 @@ body: - all-spark-notebook - base-notebook - datascience-notebook + - julia-notebook - minimal-notebook - pyspark-notebook - r-notebook diff --git a/.github/actions/download-manifests/action.yml b/.github/actions/download-manifests/action.yml index 5692f01eb6..83aa93a17e 100644 --- a/.github/actions/download-manifests/action.yml +++ b/.github/actions/download-manifests/action.yml @@ -68,6 +68,16 @@ runs: with: name: r-notebook-x86_64-history_line path: ${{ inputs.histLineDir }} + - name: Download artifact 📥 + uses: actions/download-artifact@v3 + with: + name: julia-notebook-aarch64-history_line + path: ${{ inputs.histLineDir }} + - name: Download artifact 📥 + uses: actions/download-artifact@v3 + with: + name: julia-notebook-x86_64-history_line + path: ${{ inputs.histLineDir }} - name: Download artifact 📥 uses: actions/download-artifact@v3 with: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 884f62c4ac..aa02bb825a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -24,6 +24,7 @@ on: - "base-notebook/**" - "datascience-notebook/**" - "docker-stacks-foundation/**" + - "julia-notebook/**" - "minimal-notebook/**" - "pyspark-notebook/**" - "r-notebook/**" @@ -51,6 +52,7 @@ on: - "base-notebook/**" - "datascience-notebook/**" - "docker-stacks-foundation/**" + - "julia-notebook/**" - "minimal-notebook/**" - "pyspark-notebook/**" - "r-notebook/**" @@ -162,6 +164,25 @@ jobs: runsOn: ubuntu-latest needs: [x86_64-minimal] + aarch64-julia: + uses: ./.github/workflows/docker-build-test-upload.yml + with: + parentImage: minimal-notebook + image: julia-notebook + platform: aarch64 + runsOn: ARM64 + needs: [aarch64-minimal] + if: github.repository == 'jupyter/docker-stacks' + + x86_64-julia: + uses: ./.github/workflows/docker-build-test-upload.yml + with: + parentImage: minimal-notebook + image: julia-notebook + platform: x86_64 + runsOn: ubuntu-latest + needs: [x86_64-minimal] + aarch64-tensorflow: uses: ./.github/workflows/docker-build-test-upload.yml with: @@ -254,6 +275,7 @@ jobs: minimal-notebook, scipy-notebook, r-notebook, + julia-notebook, tensorflow-notebook, datascience-notebook, pyspark-notebook, @@ -290,6 +312,7 @@ jobs: minimal-notebook, scipy-notebook, r-notebook, + julia-notebook, tensorflow-notebook, datascience-notebook, pyspark-notebook, @@ -324,6 +347,7 @@ jobs: minimal-notebook, scipy-notebook, r-notebook, + julia-notebook, tensorflow-notebook, datascience-notebook, pyspark-notebook, diff --git a/.github/workflows/hub-overview.yml b/.github/workflows/hub-overview.yml index 11e25b8fb9..2e5234e87b 100644 --- a/.github/workflows/hub-overview.yml +++ b/.github/workflows/hub-overview.yml @@ -14,6 +14,7 @@ on: - "base-notebook/README.md" - "datascience-notebook/README.md" - "docker-stacks-foundation/README.md" + - "julia-notebook/README.md" - "minimal-notebook/README.md" - "pyspark-notebook/README.md" - "r-notebook/README.md" @@ -54,6 +55,8 @@ jobs: description: "Scientific Jupyter Notebook Python Stack from https://github.com/jupyter/docker-stacks" - image: r-notebook description: "R Jupyter Notebook Stack from https://github.com/jupyter/docker-stacks" + - image: julia-notebook + description: "Julia Jupyter Notebook Stack from https://github.com/jupyter/docker-stacks" - image: tensorflow-notebook description: "Scientific Jupyter Notebook Python Stack w/ TensorFlow from https://github.com/jupyter/docker-stacks" - image: datascience-notebook diff --git a/Makefile b/Makefile index 12b0bbf41b..8a71110ab2 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ ALL_IMAGES:= \ base-notebook \ minimal-notebook \ r-notebook \ + julia-notebook \ scipy-notebook \ tensorflow-notebook \ datascience-notebook \ diff --git a/docs/images/inherit.svg b/docs/images/inherit.svg index 229366873f..0f5467a403 100644 --- a/docs/images/inherit.svg +++ b/docs/images/inherit.svg @@ -14,6 +14,7 @@ + @@ -31,6 +32,8 @@ scipy-notebook r-notebook + + julia-notebook tensorflow-notebook @@ -51,6 +54,10 @@ + + + + diff --git a/docs/using/selecting.md b/docs/using/selecting.md index 2fd2d0d50b..f93aad7072 100644 --- a/docs/using/selecting.md +++ b/docs/using/selecting.md @@ -107,6 +107,18 @@ It contains: [unixodbc](https://www.unixodbc.org) packages from [conda-forge](https://conda-forge.org/feedstock-outputs/index.html) +### jupyter/julia-notebook + +[Source on GitHub](https://github.com/jupyter/docker-stacks/tree/main/julia-notebook) | +[Dockerfile commit history](https://github.com/jupyter/docker-stacks/commits/main/julia-notebook/Dockerfile) | +[Docker Hub image tags](https://hub.docker.com/r/jupyter/julia-notebook/tags/) + +`jupyter/julia-notebook` includes popular packages from the Julia ecosystem listed below: + +- Everything in `jupyter/minimal-notebook` and its ancestor images +- The [Julia Programming Language](https://julialang.org/) +- [IJulia](https://github.com/JuliaLang/IJulia.jl) to support Julia code in Jupyter notebook + ### jupyter/scipy-notebook [Source on GitHub](https://github.com/jupyter/docker-stacks/tree/main/scipy-notebook) | @@ -211,7 +223,7 @@ The following diagram depicts the build dependency tree of the core images. (i.e Any given image inherits the complete content of all ancestor images pointing to it. [![Image inheritance -diagram](../images/inherit.svg)](http://interactive.blockdiag.com/?compression=deflate&src=eJyFjjFuwzAMRXefgvDUDDpAYaQnyNaOBQraphPCCmlIFIy0yN0rdQggI4XX9x__Z-91mEfGM_w0ACNNmLx9TSoW-ZvgCK9d5hqYxNBYJaNFgwVk65octalPYulTXk4f77CyXXLOYhDIE0Y6tODeYMwrFFw0HOboJk0y_rWV8v-yctfnBidq1KvORa5AMa4sfEVfSVtWvDjwcqusmhSnNZKoYfK6Pnj7XM0vYqYkA-1Oh53Z5RYXDHNlbVnx0Hu3Ne-_7MWcxg) +diagram](../images/inherit.svg)](http://interactive.blockdiag.com/?compression=deflate&src=eJyFjkFuwkAMRfecwsqKLuYACMEJuqPLSshJHDAZ7GjGIwSIuzPTRaWJWmX7_vP_br12Y894gucKoKcBk7fjoGKRHwQ72Gwz18AkhsYqGU0aLCDbdpWjJrVJLH3L-vPrADe2c85ZDAJ5wkgfDbg99HmFgouG3RjdoEn6n7ZS_l9W7trc4ESNWtWxyBUoxpWFr-grac6KFzue7pVVk-I0RhI1DF5vv7z5W80vYqYkHS1Oh0XjkjzjwnPTPU4Yxsqas-Kh925uvt4imKoO) ### Builds diff --git a/julia-notebook/.dockerignore b/julia-notebook/.dockerignore new file mode 100644 index 0000000000..9dea340f35 --- /dev/null +++ b/julia-notebook/.dockerignore @@ -0,0 +1,2 @@ +# Documentation +README.md diff --git a/julia-notebook/Dockerfile b/julia-notebook/Dockerfile new file mode 100644 index 0000000000..5ab6b91772 --- /dev/null +++ b/julia-notebook/Dockerfile @@ -0,0 +1,67 @@ +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. +ARG OWNER=jupyter +ARG BASE_CONTAINER=$OWNER/minimal-notebook +FROM $BASE_CONTAINER + +LABEL maintainer="Jupyter Project " + +# Fix: https://github.com/hadolint/hadolint/wiki/DL4006 +# Fix: https://github.com/koalaman/shellcheck/wiki/SC3014 +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +USER root + +# Julia installation +# Default values can be overridden at build time +# (ARGS are in lower case to distinguish them from ENV) +# Check https://julialang.org/downloads/ +ARG julia_version="1.9.1" + +# Julia dependencies +# install Julia packages in /opt/julia instead of ${HOME} +ENV JULIA_DEPOT_PATH=/opt/julia \ + JULIA_PKGDIR=/opt/julia \ + JULIA_VERSION="${julia_version}" + +WORKDIR /tmp + +# hadolint ignore=SC2046 +RUN set -x && \ + julia_arch=$(uname -m) && \ + julia_short_arch="${julia_arch}" && \ + if [ "${julia_short_arch}" == "x86_64" ]; then \ + julia_short_arch="x64"; \ + fi; \ + julia_installer="julia-${JULIA_VERSION}-linux-${julia_arch}.tar.gz" && \ + julia_major_minor=$(echo "${JULIA_VERSION}" | cut -d. -f 1,2) && \ + mkdir "/opt/julia-${JULIA_VERSION}" && \ + wget --progress=dot:giga "https://julialang-s3.julialang.org/bin/linux/${julia_short_arch}/${julia_major_minor}/${julia_installer}" && \ + tar xzf "${julia_installer}" -C "/opt/julia-${JULIA_VERSION}" --strip-components=1 && \ + rm "${julia_installer}" && \ + ln -fs /opt/julia-*/bin/julia /usr/local/bin/julia + +# Show Julia where conda libraries are \ +RUN mkdir /etc/julia && \ + echo "push!(Libdl.DL_LOAD_PATH, \"${CONDA_DIR}/lib\")" >> /etc/julia/juliarc.jl && \ + # Create JULIA_PKGDIR \ + mkdir "${JULIA_PKGDIR}" && \ + chown "${NB_USER}" "${JULIA_PKGDIR}" && \ + fix-permissions "${JULIA_PKGDIR}" + +USER ${NB_UID} + +# Add Julia packages. +# Install IJulia as jovyan and then move the kernelspec out +# to the system share location. Avoids problems with runtime UID change not +# taking effect properly on the .local folder in the jovyan home dir. +RUN julia -e 'import Pkg; Pkg.update()' && \ + julia -e 'import Pkg; Pkg.add("HDF5")' && \ + julia -e 'using Pkg; pkg"add IJulia"; pkg"precompile"' && \ + # move kernelspec out of home \ + mv "${HOME}/.local/share/jupyter/kernels/julia"* "${CONDA_DIR}/share/jupyter/kernels/" && \ + chmod -R go+rx "${CONDA_DIR}/share/jupyter" && \ + rm -rf "${HOME}/.local" && \ + fix-permissions "${JULIA_PKGDIR}" "${CONDA_DIR}/share/jupyter" + +WORKDIR "${HOME}" diff --git a/julia-notebook/README.md b/julia-notebook/README.md new file mode 100644 index 0000000000..dfca913b14 --- /dev/null +++ b/julia-notebook/README.md @@ -0,0 +1,12 @@ +# Jupyter Notebook Julia Stack + +[![docker pulls](https://img.shields.io/docker/pulls/jupyter/julia-notebook.svg)](https://hub.docker.com/r/jupyter/julia-notebook/) +[![docker stars](https://img.shields.io/docker/stars/jupyter/julia-notebook.svg)](https://hub.docker.com/r/jupyter/julia-notebook/) +[![image size](https://img.shields.io/docker/image-size/jupyter/julia-notebook/latest)](https://hub.docker.com/r/jupyter/julia-notebook/ "jupyter/julia-notebook image size") + +GitHub Actions in the project builds and pushes this image to Docker Hub. + +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/julia-notebook](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html#jupyter-julia-notebook) diff --git a/tagging/images_hierarchy.py b/tagging/images_hierarchy.py index 452d2a68c4..7a0831987f 100644 --- a/tagging/images_hierarchy.py +++ b/tagging/images_hierarchy.py @@ -64,6 +64,11 @@ class ImageDescription: taggers=[RVersionTagger()], manifests=[RPackagesManifest()], ), + "julia-notebook": ImageDescription( + parent_image="minimal-notebook", + taggers=[JuliaVersionTagger()], + manifests=[JuliaPackagesManifest()], + ), "tensorflow-notebook": ImageDescription( parent_image="scipy-notebook", taggers=[TensorflowVersionTagger()] ), diff --git a/tests/images_hierarchy.py b/tests/images_hierarchy.py index c210a1a8d9..fc0240cd94 100644 --- a/tests/images_hierarchy.py +++ b/tests/images_hierarchy.py @@ -13,6 +13,7 @@ "minimal-notebook": "base-notebook", "scipy-notebook": "minimal-notebook", "r-notebook": "minimal-notebook", + "julia-notebook": "minimal-notebook", "tensorflow-notebook": "scipy-notebook", "datascience-notebook": "scipy-notebook", "pyspark-notebook": "scipy-notebook", diff --git a/tests/julia-notebook/test_julia_exists.py b/tests/julia-notebook/test_julia_exists.py new file mode 100644 index 0000000000..5ed9d1dc5f --- /dev/null +++ b/tests/julia-notebook/test_julia_exists.py @@ -0,0 +1,18 @@ +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. +import logging + +from tests.conftest import TrackedContainer + +LOGGER = logging.getLogger(__name__) + + +def test_julia(container: TrackedContainer) -> None: + """Basic julia test""" + LOGGER.info("Test that julia is correctly installed ...") + logs = container.run_and_wait( + timeout=5, + tty=True, + command=["start.sh", "bash", "-c", "julia --version"], + ) + LOGGER.debug(logs)