Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • jupyterlab/cuda/r/base
1 result
Show changes
Commits on Source (53)
Showing
with 1022 additions and 38 deletions
......@@ -88,7 +88,7 @@ cd base && docker build \
--build-arg BASE_IMAGE=ubuntu \
--build-arg BASE_IMAGE_TAG=22.04 \
--build-arg BUILD_ON_IMAGE=glcr.b-data.ch/cuda/r/ver \
--build-arg R_VERSION=4.4.1 \
--build-arg R_VERSION=4.4.2 \
--build-arg CUDA_IMAGE_FLAVOR=devel \
-t jupyterlab/cuda/r/base \
-f latest.Dockerfile .
......@@ -224,7 +224,7 @@ docker run -it --rm \
**What makes this project different:**
1. Multi-arch: `linux/amd64`, `linux/arm64/v8`
1. Derived from [`nvidia/cuda:12.6.2-devel-ubuntu22.04`](https://hub.docker.com/r/nvidia/cuda/tags?page=1&name=12.6.2-devel-ubuntu22.04)
1. Derived from [`nvidia/cuda:12.8.0-devel-ubuntu22.04`](https://hub.docker.com/r/nvidia/cuda/tags?page=1&name=12.8.0-devel-ubuntu22.04)
* including development libraries and headers
1. TensortRT and TensorRT plugin libraries
* including development libraries and headers
......
......@@ -6,6 +6,7 @@ Topmost entry = Tag `latest`
| R | Python | SAGA[^1] | CUDA | cuBLAS | cuDNN | NCCL | TensorRT[^2] | Linux distro |
|:------|:--------|:---------|:-------|:----------|:----------|:-------|:------------------------|:-------------|
| 4.4.2 | 3.12.9 | 7.3.0 | 12.8.0 | 12.8.3.14 | 8.9.7.29 | 2.25.1 | 10.8.0.43/<br>10.3.0.26 | Ubuntu 22.04 |
| 4.4.1 | 3.12.7 | 7.3.0 | 12.6.2 | 12.6.3.3 | 8.9.7.29 | 2.23.4 | 10.6.0.26/<br>10.3.0.26 | Ubuntu 22.04 |
| 4.4.0 | 3.12.4 | 7.3.0 | 12.5.0 | 12.5.2.13 | 8.9.7.29 | 2.21.5 | 10.0.1.6 | Ubuntu 22.04 |
| 4.3.3 | 3.11.9 | 7.3.0 | 11.8.0 | 11.11.3.6 | 8.9.6.50 | 2.15.5 | 8.5.3[^3] | Ubuntu 22.04 |
......@@ -23,6 +24,7 @@ Topmost entry = Tag `latest`
| Python | CUDA | PyTorch[^4] | TensorFlow[^5] |
|:-------|:-----|:---------------|:----------------------|
| 3.12 | 12.8 | version ≥ 2.2 | version ≥ 2.16 |
| 3.12 | 12.6 | version ≥ 2.2 | version ≥ 2.16 |
| 3.12 | 12.5 | version ≥ 2.2 | version ≥ 2.16 |
| 3.11 | 11.8 | version ≥ 2.0 | 2.15 ≥ version > 2.12 |
......@@ -38,6 +40,7 @@ given.
| CUDA | Linux driver version | Windows driver version[^6] |
|:-------|:---------------------|:---------------------------|
| 12.8.0 | ≥ 570.26 | ≥ 570.65 |
| 12.6.2 | ≥ 560.35.03 | ≥ 560.94 |
| 12.5.0 | ≥ 555.42.02 | ≥ 555.85 |
| 11.8.0 | ≥ 520.61.05 | ≥ 520.06 |
......@@ -53,6 +56,7 @@ Only works with
| CUDA | Driver version 535[^7] | Driver version 470[^8] |
|:-------|:----------------------:|:----------------------:|
| 12.8.0 | 🟢 | 🔵 |
| 12.6.2 | 🟢 | 🔵 |
| 12.5.0 | 🟢 | 🔵 |
| 11.8.0 | 🟡 | 🟢 |
......
......@@ -45,7 +45,7 @@ The following startup hooks are put in place:
* set environment variables in `$(R RHOME)/etc/Renviron.site`.
* put inital RStudio settings in place.
* create user's working folder.
* [/usr/local/bin/before-notebook.d/70-qgis.sh](qgisprocess/scripts/usr/local/bin/before-notebook.d/70-qgis.sh) to
* [/usr/local/bin/before-notebook.d/70-qgis.sh](qgisprocess/scripts/usr/local/bin/before-notebook.d/70-qgis.sh) (qgisprocess images) to
* put inital QGIS settings in place.
* copy plugin 'Processing Saga NextGen Provider'.
* [/usr/local/bin/before-notebook.d/71-tensorboard.sh](base/scripts/usr/local/bin/before-notebook.d/71-tensorboard.sh)
......@@ -172,6 +172,13 @@ are installed.
* Application > Telemetry: Telemetry Level: off
* Features > Terminal > Integrated: Font Family: MesloLGS NF
* Workbench > Appearance > Color Theme: Default Dark+
* [QGIS](qgisprocess/conf/user/var/backups/skel/.local/share/QGIS/QGIS3/profiles/default/QGIS/QGIS3.ini) (qgisprocess images):
* Append `/usr/lib/python3/dist-packages` to `PYTHONPATH`.
:information_source: One distro refused to find the Python bindings to QGIS
(at `/usr/lib/python3/dist-packages/qgis`)... Kept for backwards
compatibility.
* Set UI Theme to 'Night Mapping'.
* Set OTB application folder and OTB folder.
* Zsh
* Oh My Zsh: `~/.zshrc`
* Set PATH so it includes user's private bin if it exists
......
......@@ -154,7 +154,7 @@ To install docker, follow the instructions for your platform:
```bash
cd base && docker build \
--build-arg R_VERSION=4.4.1 \
--build-arg R_VERSION=4.4.2 \
-t jupyterlab/r/base \
-f latest.Dockerfile .
```
......@@ -352,6 +352,8 @@ b-data tailors the JupyterLab images to your needs, e.g.
services on the intranet.
* Setting up the necessary environment variables so that everything works
behind a corporate proxy server.
* If supported by the NVIDIA GPU(s): Correctly handle CUDA forward compatibility
for GPU accelerated images.
Additionally, the
[JupyterHub](https://github.com/b-data/docker-deployment-jupyter) setup can be
......
......@@ -8,6 +8,7 @@ Topmost entry = Tag `latest`
| R | Python | Jupyter Hub | Jupyter Lab | code‑server (Code) | RStudio | Neovim | Git | Git LFS | Pandoc | CRAN date | Linux distro |
|:------|:--------|:------------|:------------|:-------------------|:--------------|:-------|:-------|:--------|:-------|:-----------|:-------------|
| 4.4.2 | 3.12.9 | 5.2.1 | 4.3.5 | 4.97.2 (1.97.2) | 2024.12.1+563 | 0.10.4 | 2.48.1 | 3.6.1 | 3.4 | 2025‑02‑28 | Debian 12 |
| 4.4.1 | 3.12.7 | 5.2.1 | 4.2.5 | 4.93.1 (1.93.1) | 2024.09.0+375 | 0.10.2 | 2.47.0 | 3.5.1 | 3.2 | 2024‑10‑31 | Debian 12 |
| 4.4.0 | 3.12.4 | 5.0.0 | 4.2.2 | 4.90.0 (1.90.0) | 2024.04.2+764 | n/a | 2.45.2 | 3.5.1 | 3.1.11 | 2024‑06‑14 | Debian 12 |
| 4.3.3 | 3.11.9 | 4.1.5 | 4.1.6 | 4.23.0 (1.88.0) | n/a | n/a | 2.44.0 | 3.5.1 | 3.1.11 | 2024‑04‑24 | Debian 12 |
......@@ -23,6 +24,7 @@ Topmost entry = Tag `latest`
| R | CTAN date | Quarto |
|:------|:-----------|:------------|
| 4.4.2 | 2025‑02‑28 | 1.6.42 |
| 4.4.1 | 2024‑10‑31 | 1.5.57 |
| 4.4.0 | 2024‑06‑14 | 1.4.555 |
| 4.3.3 | 2024‑04‑24 | 1.4.553 |
......@@ -38,6 +40,7 @@ Topmost entry = Tag `latest`
| R | QGIS | SAGA | OTB[^1] |
|:------|:-------|:------|:--------|
| 4.4.2 | 3.42.0 | 9.1.3 | 9.1.0 |
| 4.4.1 | 3.40.0 | 9.1.3 | 9.1.0 |
| 4.4.0 | 3.36.3 | 9.1.3 | 9.0.0 |
| 4.3.3 | 3.36.2 | 9.1.3 | 9.0.0 |
......
.env:
variables:
R_VERSION: "4.4.1"
R_VERSION: "4.4.2"
RSTUDIO_VERSION: "2024.12.1+563"
TAG_VERSION_MAJ_MIN: "false"
TAG_VERSION_MAJ: "false"
......@@ -67,6 +68,7 @@ build:latest-linux-amd64:
--build-arg BASE_IMAGE_TAG
--build-arg BUILD_ON_IMAGE
--build-arg R_VERSION
--build-arg RSTUDIO_VERSION
--build-arg CUDA_IMAGE_FLAVOR
--build-arg CUDA_IMAGE_LICENSE
--build-arg NCPUS=$((`nproc`/2+1))
......@@ -114,6 +116,7 @@ build:latest-linux-arm64v8:
--build-arg BASE_IMAGE_TAG
--build-arg BUILD_ON_IMAGE
--build-arg R_VERSION
--build-arg RSTUDIO_VERSION
--build-arg CUDA_IMAGE_FLAVOR
--build-arg CUDA_IMAGE_LICENSE
--build-arg NCPUS=$((`nproc`/2+1))
......
ARG BASE_IMAGE=debian
ARG BASE_IMAGE_TAG=12
ARG BUILD_ON_IMAGE=glcr.b-data.ch/r/ver
ARG R_VERSION=4.4.2
ARG CUDA_IMAGE_FLAVOR
ARG NB_USER=jovyan
ARG NB_UID=1000
ARG JUPYTERHUB_VERSION=5.2.1
ARG JUPYTERLAB_VERSION=4.3.5
ARG CODE_BUILTIN_EXTENSIONS_DIR=/opt/code-server/lib/vscode/extensions
ARG CODE_SERVER_VERSION=4.97.2
ARG RSTUDIO_VERSION=2024.12.1+563
ARG NEOVIM_VERSION=0.10.4
ARG GIT_VERSION=2.48.1
ARG GIT_LFS_VERSION=3.6.1
ARG PANDOC_VERSION=3.4
FROM ${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} AS files
ARG RSTUDIO_VERSION
ARG NB_UID
ENV NB_GID=100
RUN mkdir /files
COPY assets /files
COPY conf/ipython /files
COPY conf/jupyter /files
COPY conf/jupyterlab /files
COPY conf/rstudio /files
COPY conf/shell /files
COPY conf${CUDA_IMAGE:+/cuda}/shell /files
COPY conf/user /files
COPY scripts /files
## Copy content of skel directory to backup
RUN cp -a /files/etc/skel/. /files/var/backups/skel \
&& chown -R ${NB_UID}:${NB_GID} /files/var/backups/skel \
## Copy custom fonts
&& mkdir -p /files/usr/local/share/jupyter/lab/static/assets \
&& cp -a /files/opt/code-server/src/browser/media/css \
/files/usr/local/share/jupyter/lab/static/assets \
&& cp -a /files/opt/code-server/src/browser/media/fonts \
/files/usr/local/share/jupyter/lab/static/assets \
&& mkdir -p /files/etc/rstudio/fonts \
&& cp "/files/opt/code-server/src/browser/media/fonts/MesloLGS NF Regular.woff" \
"/files/etc/rstudio/fonts/MesloLGS NF.woff" \
&& cp "/files/opt/code-server/src/browser/media/fonts/MesloLGS NF Regular.woff2" \
"/files/etc/rstudio/fonts/MesloLGS NF.woff2" \
&& if [ -n "${CUDA_VERSION}" ]; then \
## Use standard R terminal for CUDA images
## radian forces usage of /usr[/local]/bin/python
sed -i 's|/usr/local/bin/radian|/usr/local/bin/R|g' \
/files/var/backups/skel/.local/share/code-server/User/settings.json; \
## Use entrypoint of CUDA image
mv /opt/nvidia/entrypoint.d /opt/nvidia/nvidia_entrypoint.sh \
/files/usr/local/bin; \
mv /files/usr/local/bin/start.sh \
/files/usr/local/bin/entrypoint.d/99-start.sh; \
mv /files/usr/local/bin/nvidia_entrypoint.sh \
/files/usr/local/bin/start.sh; \
fi \
&& if [ -z "${RSTUDIO_VERSION}" ]; then \
rm -rf /files/etc/rstudio \
/files/usr/local/bin/before-notebook.d/*-rstudio.sh \
/files/var/backups/skel/.config; \
fi \
## Ensure file modes are correct when using CI
## Otherwise set to 777 in the target image
&& find /files -type d -exec chmod 755 {} \; \
&& find /files -type f -exec chmod 644 {} \; \
&& find /files/usr/local/bin -type f -exec chmod 755 {} \; \
&& find /files/etc/profile.d -type f -exec chmod 755 {} \;
FROM glcr.b-data.ch/neovim/nvsi:${NEOVIM_VERSION} AS nvsi
FROM glcr.b-data.ch/git/gsi/${GIT_VERSION}/${BASE_IMAGE}:${BASE_IMAGE_TAG} AS gsi
FROM glcr.b-data.ch/git-lfs/glfsi:${GIT_LFS_VERSION} AS glfsi
FROM ${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} AS base
FROM ${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} AS base-rstudio
ARG RSTUDIO_VERSION
ENV RSTUDIO_VERSION=${RSTUDIO_VERSION}
## Connect to RStudio via unix socket
ENV JUPYTER_RSESSION_PROXY_USE_SOCKET=1
FROM base${RSTUDIO_VERSION:+-rstudio}
ARG NCPUS=1
ARG DEBIAN_FRONTEND=noninteractive
ARG BUILD_ON_IMAGE
ARG CUDA_IMAGE_FLAVOR
ARG NB_USER
ARG NB_UID
ARG JUPYTERHUB_VERSION
ARG JUPYTERLAB_VERSION
ARG CODE_BUILTIN_EXTENSIONS_DIR
ARG CODE_SERVER_VERSION
ARG NEOVIM_VERSION
ARG GIT_VERSION
ARG GIT_LFS_VERSION
ARG PANDOC_VERSION
ARG BUILD_START
ARG CODE_WORKDIR
ARG CUDA_IMAGE_LICENSE=${CUDA_VERSION:+"NVIDIA Deep Learning Container License"}
ARG IMAGE_LICENSE=${CUDA_IMAGE_LICENSE:-"MIT"}
ARG IMAGE_SOURCE=https://gitlab.b-data.ch/jupyterlab/r/docker-stack
ARG IMAGE_VENDOR="b-data GmbH"
ARG IMAGE_AUTHORS="Olivier Benz <olivier.benz@b-data.ch>"
LABEL org.opencontainers.image.licenses="$IMAGE_LICENSE" \
org.opencontainers.image.source="$IMAGE_SOURCE" \
org.opencontainers.image.vendor="$IMAGE_VENDOR" \
org.opencontainers.image.authors="$IMAGE_AUTHORS"
ENV PARENT_IMAGE=${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} \
NB_USER=${NB_USER} \
NB_UID=${NB_UID} \
JUPYTERHUB_VERSION=${JUPYTERHUB_VERSION} \
JUPYTERLAB_VERSION=${JUPYTERLAB_VERSION} \
CODE_SERVER_VERSION=${CODE_SERVER_VERSION} \
NEOVIM_VERSION=${NEOVIM_VERSION} \
GIT_VERSION=${GIT_VERSION} \
GIT_LFS_VERSION=${GIT_LFS_VERSION} \
PANDOC_VERSION=${PANDOC_VERSION} \
BUILD_DATE=${BUILD_START}
ENV NB_GID=100
## Installing V8 on Linux, the alternative way
## https://ropensci.org/blog/2020/11/12/installing-v8
ENV DOWNLOAD_STATIC_LIBV8=1
## Disable prompt to install miniconda
ENV RETICULATE_MINICONDA_ENABLED=0
## Install Neovim
COPY --from=nvsi /usr/local /usr/local
## Install Git
COPY --from=gsi /usr/local /usr/local
## Install Git LFS
COPY --from=glfsi /usr/local /usr/local
USER root
RUN dpkgArch="$(dpkg --print-architecture)" \
## Unminimise if the system has been minimised
&& if [ $(command -v unminimize) ]; then \
yes | unminimize; \
fi \
&& apt-get update \
&& apt-get -y install --no-install-recommends \
bash-completion \
build-essential \
curl \
file \
fontconfig \
g++ \
gcc \
gfortran \
gnupg \
htop \
info \
jq \
libclang-dev \
man-db \
nano \
ncdu \
procps \
psmisc \
screen \
sudo \
swig \
tmux \
vim-tiny \
wget \
zsh \
## Neovim: Additional runtime recommendations
ripgrep \
## Git: Additional runtime dependencies
libcurl3-gnutls \
liberror-perl \
## Git: Additional runtime recommendations
less \
ssh-client \
## Python: Additional dev dependencies
&& if [ -z "$PYTHON_VERSION" ]; then \
apt-get -y install --no-install-recommends \
python3-dev \
## Install Python package installer
## (dep: python3-distutils, python3-setuptools and python3-wheel)
python3-pip \
## Install venv module for python3
python3-venv; \
## make some useful symlinks that are expected to exist
## ("/usr/bin/python" and friends)
for src in pydoc3 python3 python3-config; do \
dst="$(echo "$src" | tr -d 3)"; \
if [ -s "/usr/bin/$src" ] && [ ! -e "/usr/bin/$dst" ]; then \
ln -svT "$src" "/usr/bin/$dst"; \
fi \
done; \
else \
## Force update pip, setuptools and wheel
pip install --upgrade --force-reinstall \
pip \
setuptools \
wheel; \
fi \
## Install font MesloLGS NF
&& mkdir -p /usr/share/fonts/truetype/meslo \
&& curl -sL https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf -o "/usr/share/fonts/truetype/meslo/MesloLGS NF Regular.ttf" \
&& curl -sL https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf -o "/usr/share/fonts/truetype/meslo/MesloLGS NF Bold.ttf" \
&& curl -sL https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf -o "/usr/share/fonts/truetype/meslo/MesloLGS NF Italic.ttf" \
&& curl -sL https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf -o "/usr/share/fonts/truetype/meslo/MesloLGS NF Bold Italic.ttf" \
&& fc-cache -fsv \
## Git: Set default branch name to main
&& git config --system init.defaultBranch main \
## Git: Store passwords for one hour in memory
&& git config --system credential.helper "cache --timeout=3600" \
## Git: Merge the default branch from the default remote when "git pull" is run
&& git config --system pull.rebase false \
## Install pandoc
&& curl -sLO https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-1-${dpkgArch}.deb \
&& dpkg -i pandoc-${PANDOC_VERSION}-1-${dpkgArch}.deb \
&& rm pandoc-${PANDOC_VERSION}-1-${dpkgArch}.deb \
## Delete potential user with UID 1000
&& if grep -q 1000 /etc/passwd; then \
userdel --remove $(id -un 1000); \
fi \
## Do not set user limits for sudo/sudo-i
&& sed -i 's/.*pam_limits.so/#&/g' /etc/pam.d/sudo \
&& if [ -f "/etc/pam.d/sudo-i" ]; then \
sed -i 's/.*pam_limits.so/#&/g' /etc/pam.d/sudo-i; \
fi \
## Add user
&& useradd -l -m -s $(which zsh) -N -u ${NB_UID} ${NB_USER} \
## Mark home directory as populated
&& touch /home/${NB_USER}/.populated \
&& chown ${NB_UID}:${NB_GID} /home/${NB_USER}/.populated \
&& chmod go+w /home/${NB_USER}/.populated \
## Create backup directory for home directory
&& mkdir -p /var/backups/skel \
&& chown ${NB_UID}:${NB_GID} /var/backups/skel \
## Install Tini
&& curl -sL https://github.com/krallin/tini/releases/download/v0.19.0/tini-${dpkgArch} -o /usr/local/bin/tini \
&& chmod +x /usr/local/bin/tini \
## Clean up
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
${HOME}/.cache
ENV PATH=/opt/code-server/bin:$PATH \
CS_DISABLE_GETTING_STARTED_OVERRIDE=1
## Install code-server
RUN mkdir /opt/code-server \
&& cd /opt/code-server \
&& curl -sL https://github.com/coder/code-server/releases/download/v${CODE_SERVER_VERSION}/code-server-${CODE_SERVER_VERSION}-linux-$(dpkg --print-architecture).tar.gz | tar zxf - --no-same-owner --strip-components=1 \
## Copy custom fonts
&& mkdir -p /opt/code-server/src/browser/media/fonts \
&& cp -a /usr/share/fonts/truetype/meslo/*.ttf /opt/code-server/src/browser/media/fonts \
## Include custom fonts
&& sed -i 's|</head>| <link rel="preload" href="{{BASE}}/_static/src/browser/media/fonts/MesloLGS NF Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">\n </head>|g' /opt/code-server/lib/vscode/out/vs/code/browser/workbench/workbench.html \
&& sed -i 's|</head>| <link rel="preload" href="{{BASE}}/_static/src/browser/media/fonts/MesloLGS NF Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">\n </head>|g' /opt/code-server/lib/vscode/out/vs/code/browser/workbench/workbench.html \
&& sed -i 's|</head>| <link rel="preload" href="{{BASE}}/_static/src/browser/media/fonts/MesloLGS NF Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">\n </head>|g' /opt/code-server/lib/vscode/out/vs/code/browser/workbench/workbench.html \
&& sed -i 's|</head>| <link rel="preload" href="{{BASE}}/_static/src/browser/media/fonts/MesloLGS NF Bold Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">\n </head>|g' /opt/code-server/lib/vscode/out/vs/code/browser/workbench/workbench.html \
&& sed -i 's|</head>| <link rel="stylesheet" type="text/css" href="{{BASE}}/_static/src/browser/media/css/fonts.css">\n </head>|g' /opt/code-server/lib/vscode/out/vs/code/browser/workbench/workbench.html \
## Install code-server extensions
&& cd /tmp \
&& curl -sLO https://dl.b-data.ch/vsix/piotrpalarz.vscode-gitignore-generator-1.0.3.vsix \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension piotrpalarz.vscode-gitignore-generator-1.0.3.vsix \
&& curl -sLO https://dl.b-data.ch/vsix/mutantdino.resourcemonitor-1.0.7.vsix \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension mutantdino.resourcemonitor-1.0.7.vsix \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension alefragnani.project-manager \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension GitHub.vscode-pull-request-github \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension GitLab.gitlab-workflow \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension ms-python.python \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension ms-toolsai.jupyter \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension christian-kohler.path-intellisense \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension eamodio.gitlens@11.7.0 \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension mhutchie.git-graph \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension redhat.vscode-yaml \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension grapecity.gc-excelviewer \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension editorconfig.editorconfig \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension DavidAnson.vscode-markdownlint \
## Create folders temp and tmp for Jupyter extension
&& cd /opt/code-server/lib/vscode/extensions/ms-toolsai.jupyter-* \
&& mkdir -m 1777 temp \
&& mkdir -m 1777 tmp \
## Clean up
&& rm -rf /tmp/* \
${HOME}/.config \
${HOME}/.local
## Install RStudio
RUN if [ -n "${RSTUDIO_VERSION}" ]; then \
dpkgArch="$(dpkg --print-architecture)"; \
. /etc/os-release; \
apt-get update; \
## Install lsb-release
if [ "$ID" = "debian" ]; then \
dpkg --compare-versions "$VERSION_ID" lt "12"; \
condDebian=$?; \
fi; \
if [ "$ID" = "ubuntu" ]; then \
dpkg --compare-versions "$VERSION_ID" lt "23.04"; \
condUbuntu=$?; \
fi; \
if [ "$condDebian" = "0" ]; then \
curl -sL \
http://mirrors.kernel.org/debian/pool/main/l/lsb-release-minimal/lsb-release_12.0-1_all.deb \
-o lsb-release.deb; \
dpkg -i lsb-release.deb; \
rm lsb-release.deb; \
elif [ "$condUbuntu" = "0" ]; then \
curl -sL \
http://mirrors.kernel.org/ubuntu/pool/main/l/lsb-release-minimal/lsb-release_12.0-2_all.deb \
-o lsb-release.deb; \
dpkg -i lsb-release.deb; \
rm lsb-release.deb; \
else \
apt-get -y install --no-install-recommends lsb-release; \
fi; \
## Map Ubuntu codename
if [ "$ID" = "debian" ]; then \
case "$VERSION_CODENAME" in \
bullseye) UBUNTU_CODENAME="focal" ;; \
bookworm) UBUNTU_CODENAME="jammy" ;; \
*) echo "error: Debian $VERSION unsupported"; exit 1 ;; \
esac; \
fi; \
## Install RStudio
apt-get -y install --no-install-recommends \
libapparmor1 \
libpq5 \
libssl-dev; \
rm -rf /var/lib/apt/lists/*; \
DOWNLOAD_FILE=rstudio-server-$(echo $RSTUDIO_VERSION | tr + -)-$dpkgArch.deb; \
wget --progress=dot:mega \
"https://download2.rstudio.org/server/$UBUNTU_CODENAME/$dpkgArch/$DOWNLOAD_FILE" || \
wget --progress=dot:mega \
"https://s3.amazonaws.com/rstudio-ide-build/server/$UBUNTU_CODENAME/$dpkgArch/$DOWNLOAD_FILE"; \
dpkg -i "$DOWNLOAD_FILE"; \
rm "$DOWNLOAD_FILE"; \
## Enable rstudio-server and rserver system-wide
ln -fs /usr/lib/rstudio-server/bin/rstudio-server /usr/local/bin; \
ln -fs /usr/lib/rstudio-server/bin/rserver /usr/local/bin; \
## Copy custom fonts
cp "/opt/code-server/src/browser/media/fonts/MesloLGS NF Regular.ttf" \
"/etc/rstudio/fonts/MesloLGS NF.ttf"; \
fi
## Install JupyterLab
RUN export PIP_BREAK_SYSTEM_PACKAGES=1 \
&& pip install \
jupyter-server-proxy \
jupyterhub==${JUPYTERHUB_VERSION} \
jupyterlab==${JUPYTERLAB_VERSION} \
jupyterlab-git \
jupyterlab-lsp \
notebook \
nbclassic \
nbconvert \
python-lsp-server[all] \
${RSTUDIO_VERSION:+jupyter-rsession-proxy} \
## Jupyter Server Proxy: Set maximum allowed HTTP body size to 10 GiB
&& sed -i 's/AsyncHTTPClient(/AsyncHTTPClient(max_body_size=10737418240, /g' \
/usr/local/lib/python*/*-packages/jupyter_server_proxy/handlers.py \
## Jupyter Server Proxy: Set maximum allowed websocket message size to 1 GiB
&& sed -i 's/"_default_max_message_size",.*$/"_default_max_message_size", 1024 \* 1024 \* 1024/g' \
/usr/local/lib/python*/*-packages/jupyter_server_proxy/websocket.py \
&& sed -i 's/_default_max_message_size =.*$/_default_max_message_size = 1024 \* 1024 \* 1024/g' \
/usr/local/lib/python*/*-packages/tornado/websocket.py \
## Copy custom fonts
&& mkdir -p /usr/local/share/jupyter/lab/static/assets/fonts \
&& cp -a /usr/share/fonts/truetype/meslo/*.ttf /usr/local/share/jupyter/lab/static/assets/fonts \
## Include custom fonts
&& sed -i 's|</head>|<link rel="preload" href="{{page_config.fullStaticUrl}}/assets/fonts/MesloLGS NF Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous"></head>|g' /usr/local/share/jupyter/lab/static/index.html \
&& sed -i 's|</head>|<link rel="preload" href="{{page_config.fullStaticUrl}}/assets/fonts/MesloLGS NF Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous"></head>|g' /usr/local/share/jupyter/lab/static/index.html \
&& sed -i 's|</head>|<link rel="preload" href="{{page_config.fullStaticUrl}}/assets/fonts/MesloLGS NF Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous"></head>|g' /usr/local/share/jupyter/lab/static/index.html \
&& sed -i 's|</head>|<link rel="preload" href="{{page_config.fullStaticUrl}}/assets/fonts/MesloLGS NF Bold Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous"></head>|g' /usr/local/share/jupyter/lab/static/index.html \
&& sed -i 's|</head>|<link rel="stylesheet" type="text/css" href="{{page_config.fullStaticUrl}}/assets/css/fonts.css"></head>|g' /usr/local/share/jupyter/lab/static/index.html \
## Clean up
&& rm -rf /tmp/* \
${HOME}/.cache
## Install R related stuff
RUN apt-get update \
&& apt-get -y install --no-install-recommends \
## Current ZeroMQ library for R pbdZMQ
libzmq3-dev \
## Required for R extension
libcairo2-dev \
libcurl4-openssl-dev \
libfontconfig1-dev \
libssl-dev \
libtiff-dev \
libxml2-dev \
## Install radian
&& export PIP_BREAK_SYSTEM_PACKAGES=1 \
&& pip install radian \
## Provide NVBLAS-enabled radian_
## Enabled at runtime and only if nvidia-smi and at least one GPU are present
&& if [ ! -z "$CUDA_IMAGE" ]; then \
nvblasLib="$(cd $CUDA_HOME/lib* && ls libnvblas.so* | head -n 1)"; \
cp -a $(which radian) $(which radian)_; \
echo '#!/bin/bash' > $(which radian)_; \
echo "command -v nvidia-smi >/dev/null && nvidia-smi -L | grep 'GPU[[:space:]]\?[[:digit:]]\+' >/dev/null && export LD_PRELOAD=$nvblasLib" \
>> $(which radian)_; \
echo "$(which radian) \"\${@}\"" >> $(which radian)_; \
fi \
## Install httpgd
## Archived on 2025-02-14 as requires archived package 'unigd'.
&& install2.r --error --skipinstalled -n $NCPUS \
unigd \
AsioHeaders \
&& curl -sLO https://cran.r-project.org/src/contrib/Archive/httpgd/httpgd_2.0.2.tar.gz \
&& R CMD INSTALL httpgd_2.0.2.tar.gz \
&& rm httpgd_2.0.2.tar.gz \
## Install the R kernel for Jupyter, languageserver and httpgd
&& install2.r --error --deps TRUE --skipinstalled -n $NCPUS \
IRkernel \
languageserver \
httpgd \
&& Rscript -e "IRkernel::installspec(user = FALSE, displayname = paste('R', Sys.getenv('R_VERSION')))" \
## Get rid of libcairo2-dev and its dependencies (incl. python3)
&& apt-get -y purge libcairo2-dev \
&& apt-get -y autoremove \
## IRkernel: Enable 'image/svg+xml' instead of 'image/png' for plot display
## IRkernel: Enable 'application/pdf' for PDF conversion
&& echo "options(jupyter.plot_mimetypes = c('text/plain', 'image/svg+xml', 'application/pdf'))" \
>> $(R RHOME)/etc/Rprofile.site \
## IRkernel: Include user's private bin in PATH
&& echo "if (dir.exists(file.path(Sys.getenv('HOME'), 'bin')) &&" \
>> $(R RHOME)/etc/Rprofile.site \
&& echo ' !grepl(file.path(Sys.getenv('\''HOME'\''), '\''bin'\''), Sys.getenv('\''PATH'\''))) {' \
>> $(R RHOME)/etc/Rprofile.site \
&& echo " Sys.setenv(PATH = paste(file.path(Sys.getenv('HOME'), 'bin'), Sys.getenv('PATH')," \
>> $(R RHOME)/etc/Rprofile.site \
&& echo " sep = .Platform\$path.sep))}" \
>> $(R RHOME)/etc/Rprofile.site \
&& echo "if (dir.exists(file.path(Sys.getenv('HOME'), '.local', 'bin')) &&" \
>> $(R RHOME)/etc/Rprofile.site \
&& echo ' !grepl(file.path(Sys.getenv('\''HOME'\''), '\''.local'\'', '\''bin'\''), Sys.getenv('\''PATH'\''))) {' \
>> $(R RHOME)/etc/Rprofile.site \
&& echo " Sys.setenv(PATH = paste(file.path(Sys.getenv('HOME'), '.local', 'bin'), Sys.getenv('PATH')," \
>> $(R RHOME)/etc/Rprofile.site \
&& echo " sep = .Platform\$path.sep))}" \
>> $(R RHOME)/etc/Rprofile.site \
## Install code-server extension
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension REditorSupport.r \
## REditorSupport.r: Disable help panel and revert to old behaviour
&& echo "options(vsc.helpPanel = FALSE)" >> $(R RHOME)/etc/Rprofile.site \
## Change ownership and permission of $(R RHOME)/etc/*.site
&& chown :"$NB_GID" "$(R RHOME)/etc" "$(R RHOME)/etc/"*.site \
&& chmod g+w "$(R RHOME)/etc" "$(R RHOME)/etc/"*.site \
## Strip libraries of binary packages installed from P3M
&& RLS=$(Rscript -e "cat(Sys.getenv('R_LIBS_SITE'))") \
&& strip ${RLS}/*/libs/*.so \
## Clean up
&& rm -rf /tmp/* \
/var/lib/apt/lists/* \
${HOME}/.cache \
${HOME}/.config \
${HOME}/.ipython \
${HOME}/.local
## Switch back to ${NB_USER} to avoid accidental container runs as root
USER ${NB_USER}
ENV HOME=/home/${NB_USER} \
CODE_WORKDIR=${CODE_WORKDIR:-/home/${NB_USER}/projects} \
SHELL=/usr/bin/zsh \
TERM=xterm-256color
WORKDIR ${HOME}
## Install Oh My Zsh with Powerlevel10k theme
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended \
&& git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${HOME}/.oh-my-zsh/custom/themes/powerlevel10k \
&& ${HOME}/.oh-my-zsh/custom/themes/powerlevel10k/gitstatus/install -f \
&& sed -i 's/ZSH="\/home\/jovyan\/.oh-my-zsh"/ZSH="$HOME\/.oh-my-zsh"/g' ${HOME}/.zshrc \
&& sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="powerlevel10k\/powerlevel10k"/g' ${HOME}/.zshrc \
&& echo "\n# set PATH so it includes user's private bin if it exists\nif [ -d \"\$HOME/bin\" ] && [[ \"\$PATH\" != *\"\$HOME/bin\"* ]] ; then\n PATH=\"\$HOME/bin:\$PATH\"\nfi" | tee -a ${HOME}/.bashrc ${HOME}/.zshrc \
&& echo "\n# set PATH so it includes user's private bin if it exists\nif [ -d \"\$HOME/.local/bin\" ] && [[ \"\$PATH\" != *\"\$HOME/.local/bin\"* ]] ; then\n PATH=\"\$HOME/.local/bin:\$PATH\"\nfi" | tee -a ${HOME}/.bashrc ${HOME}/.zshrc \
&& echo "\n# Update last-activity timestamps while in screen/tmux session\nif [ ! -z \"\$TMUX\" -o ! -z \"\$STY\" ] ; then\n busy &\nfi" >> ${HOME}/.bashrc \
&& echo "\n# Update last-activity timestamps while in screen/tmux session\nif [ ! -z \"\$TMUX\" -o ! -z \"\$STY\" ] ; then\n setopt nocheckjobs\n busy &\nfi" >> ${HOME}/.zshrc \
&& echo "\n# To customize prompt, run \`p10k configure\` or edit ~/.p10k.zsh." >> ${HOME}/.zshrc \
&& echo "[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh" >> ${HOME}/.zshrc \
## Create user's private bin
&& mkdir -p ${HOME}/.local/bin \
## Record population timestamp
&& date -uIseconds > ${HOME}/.populated \
## Create backup of home directory
&& cp -a ${HOME}/. /var/backups/skel
## Copy files as late as possible to avoid cache busting
COPY --from=files /files /
COPY --from=files /files/var/backups/skel ${HOME}
ARG JUPYTER_PORT=8888
ENV JUPYTER_PORT=${JUPYTER_PORT}
EXPOSE $JUPYTER_PORT
## Configure container startup
ENTRYPOINT ["tini", "-g", "--", "start.sh"]
CMD ["start-notebook.sh"]
......@@ -10,8 +10,8 @@ from pathlib import Path
from jupyter_core.paths import jupyter_data_dir
c = get_config() # noqa: F821 # type: ignore
c.ServerApp.ip = "0.0.0.0"
c.ServerApp.port = 8888
# Listen on all interfaces (IPv4 and IPv6)
c.ServerApp.ip = ""
#c.ServerApp.open_browser = False
# https://github.com/jupyter/notebook/issues/3130
......
......@@ -7,14 +7,14 @@ ARG CUDA_IMAGE_FLAVOR
ARG NB_USER=jovyan
ARG NB_UID=1000
ARG JUPYTERHUB_VERSION=5.2.1
ARG JUPYTERLAB_VERSION=4.2.5
ARG JUPYTERLAB_VERSION=4.3.5
ARG CODE_BUILTIN_EXTENSIONS_DIR=/opt/code-server/lib/vscode/extensions
ARG CODE_SERVER_VERSION=4.93.1
ARG RSTUDIO_VERSION=2024.09.0+375
ARG NEOVIM_VERSION=0.10.2
ARG GIT_VERSION=2.47.0
ARG GIT_LFS_VERSION=3.5.1
ARG PANDOC_VERSION=3.2
ARG CODE_SERVER_VERSION=4.97.2
ARG RSTUDIO_VERSION
ARG NEOVIM_VERSION=0.10.4
ARG GIT_VERSION=2.48.1
ARG GIT_LFS_VERSION=3.6.1
ARG PANDOC_VERSION=3.4
FROM ${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} AS files
......@@ -78,7 +78,18 @@ FROM glcr.b-data.ch/neovim/nvsi:${NEOVIM_VERSION} AS nvsi
FROM glcr.b-data.ch/git/gsi/${GIT_VERSION}/${BASE_IMAGE}:${BASE_IMAGE_TAG} AS gsi
FROM glcr.b-data.ch/git-lfs/glfsi:${GIT_LFS_VERSION} AS glfsi
FROM ${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR}
FROM ${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} AS base
FROM ${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} AS base-rstudio
ARG RSTUDIO_VERSION
ENV RSTUDIO_VERSION=${RSTUDIO_VERSION}
## Connect to RStudio via unix socket
ENV JUPYTER_RSESSION_PROXY_USE_SOCKET=1
FROM base${RSTUDIO_VERSION:+-rstudio}
ARG NCPUS=1
......@@ -92,7 +103,6 @@ ARG JUPYTERHUB_VERSION
ARG JUPYTERLAB_VERSION
ARG CODE_BUILTIN_EXTENSIONS_DIR
ARG CODE_SERVER_VERSION
ARG RSTUDIO_VERSION
ARG NEOVIM_VERSION
ARG GIT_VERSION
ARG GIT_LFS_VERSION
......@@ -118,7 +128,6 @@ ENV PARENT_IMAGE=${BUILD_ON_IMAGE}:${R_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMA
JUPYTERHUB_VERSION=${JUPYTERHUB_VERSION} \
JUPYTERLAB_VERSION=${JUPYTERLAB_VERSION} \
CODE_SERVER_VERSION=${CODE_SERVER_VERSION} \
RSTUDIO_VERSION=${RSTUDIO_VERSION} \
NEOVIM_VERSION=${NEOVIM_VERSION} \
GIT_VERSION=${GIT_VERSION} \
GIT_LFS_VERSION=${GIT_LFS_VERSION} \
......@@ -410,6 +419,14 @@ RUN apt-get update \
>> $(which radian)_; \
echo "$(which radian) \"\${@}\"" >> $(which radian)_; \
fi \
## Install httpgd
## Archived on 2025-02-14 as requires archived package 'unigd'.
&& install2.r --error --skipinstalled -n $NCPUS \
unigd \
AsioHeaders \
&& curl -sLO https://cran.r-project.org/src/contrib/Archive/httpgd/httpgd_2.0.2.tar.gz \
&& R CMD INSTALL httpgd_2.0.2.tar.gz \
&& rm httpgd_2.0.2.tar.gz \
## Install the R kernel for Jupyter, languageserver and httpgd
&& install2.r --error --deps TRUE --skipinstalled -n $NCPUS \
IRkernel \
......@@ -491,7 +508,10 @@ RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master
COPY --from=files /files /
COPY --from=files /files/var/backups/skel ${HOME}
EXPOSE 8888
ARG JUPYTER_PORT=8888
ENV JUPYTER_PORT=${JUPYTER_PORT}
EXPOSE $JUPYTER_PORT
## Configure container startup
ENTRYPOINT ["tini", "-g", "--", "start.sh"]
......
......@@ -5,6 +5,9 @@
set -e
if [ "$(id -u)" == 0 ] ; then
if [ "${NB_USER}" = "root" ] && [ "${NB_UID}" = "$(id -u "${NB_USER}")" ] && [ "${NB_GID}" = "$(id -g "${NB_USER}")" ]; then
HOME="/home/root"
fi
# Create user's R package library
RLU=$(run_user_group Rscript -e "cat(Sys.getenv('R_LIBS_USER'))")
run_user_group mkdir -p "$RLU"
......
......@@ -4,10 +4,7 @@
set -e
# set default ip to 0.0.0.0
if [[ "${NOTEBOOK_ARGS} $*" != *"--ip="* ]]; then
NOTEBOOK_ARGS="--ip=0.0.0.0 ${NOTEBOOK_ARGS}"
fi
# JupyterHub singleuser arguments are set using environment variables
echo "Executing: jupyterhub-singleuser" "${NOTEBOOK_ARGS}" "$@"
# shellcheck disable=SC1091,SC2086
......
......@@ -116,8 +116,8 @@ if [ "$(id -u)" == 0 ]; then
userdel "${NB_USER}"
useradd --no-log-init --home "/home/${NB_USER}${DOMAIN:+@$DOMAIN}" --shell "$(which zsh)" --uid "${NB_UID}" --gid "${NB_GID}" --groups 100 "${NB_USER}"
else
# Otherwise, and if not the jovyan user, add it to the default group
if [[ "${NB_USER}" != "jovyan" ]]; then
# Otherwise, and if not jovyan or root, add it to the default group
if [[ "${NB_USER}" != "jovyan" && "${NB_USER}" != "root" ]]; then
usermod -a -G 100 "${NB_USER}"
fi
fi
......
ARG BASE_IMAGE=debian
ARG BASE_IMAGE_TAG=12
ARG BUILD_ON_IMAGE
ARG R_VERSION=4.4.2
ARG NODE_VERSION=20.18.1
ARG CODE_BUILTIN_EXTENSIONS_DIR=/opt/code-server/lib/vscode/extensions
FROM glcr.b-data.ch/nodejs/nsi/${NODE_VERSION}/${BASE_IMAGE}:${BASE_IMAGE_TAG} AS nsi
FROM ${BUILD_ON_IMAGE}:${R_VERSION}
ARG DEBIAN_FRONTEND=noninteractive
ARG BUILD_ON_IMAGE
ARG NODE_VERSION
ARG CODE_BUILTIN_EXTENSIONS_DIR
ARG BUILD_START
ENV PARENT_IMAGE=${BUILD_ON_IMAGE}:${R_VERSION} \
NODE_VERSION=${NODE_VERSION} \
BUILD_DATE=${BUILD_START}
## Prevent Corepack showing the URL when it needs to download software
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
## Install Node.js
COPY --from=nsi /usr/local /usr/local
USER root
ENV HOME=/root
WORKDIR ${HOME}
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bats \
libkrb5-dev \
libsecret-1-dev \
libx11-dev \
libxkbfile-dev \
libxt6 \
quilt \
rsync \
&& if [ -n "$PYTHON_VERSION" ]; then \
## make some useful symlinks that are expected to exist
## ("/usr/bin/python" and friends)
for src in pydoc3 python3 python3-config; do \
dst="$(echo "$src" | tr -d 3)"; \
if [ -s "/usr/bin/$src" ] && [ ! -e "/usr/bin/$dst" ]; then \
ln -svT "$src" "/usr/bin/$dst"; \
fi \
done; \
fi \
## Clean up Node.js installation
&& bash -c 'rm -f /usr/local/bin/{docker-entrypoint.sh,yarn*}' \
&& bash -c 'mv /usr/local/{CHANGELOG.md,LICENSE,README.md} \
/usr/local/share/doc/node' \
## Enable corepack (Yarn, pnpm)
&& corepack enable \
## Install nFPM
&& echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' \
| tee /etc/apt/sources.list.d/goreleaser.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends nfpm \
## Install code-server extensions
&& code-server --extensions-dir "$CODE_BUILTIN_EXTENSIONS_DIR" \
--install-extension dbaeumer.vscode-eslint \
&& code-server --extensions-dir "$CODE_BUILTIN_EXTENSIONS_DIR" \
--install-extension esbenp.prettier-vscode \
&& code-server --extensions-dir "$CODE_BUILTIN_EXTENSIONS_DIR" \
--install-extension ms-python.black-formatter \
&& code-server --extensions-dir "$CODE_BUILTIN_EXTENSIONS_DIR" \
--install-extension timonwong.shellcheck \
## Enable shellcheck system-wide
&& ln -sf "$CODE_BUILTIN_EXTENSIONS_DIR"/timonwong.shellcheck-*/binaries/*/*/shellcheck \
/usr/local/bin/shellcheck \
## Clean up
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
"$HOME/.config" \
"$HOME/.local"
## Switch back to ${NB_USER} to avoid accidental container runs as root
USER ${NB_USER}
ENV HOME=/home/${NB_USER}
WORKDIR ${HOME}
......@@ -3,7 +3,7 @@ ARG BASE_IMAGE_TAG=12
ARG BUILD_ON_IMAGE
ARG R_VERSION
ARG NODE_VERSION=20.18.0
ARG NODE_VERSION=20.18.1
ARG CODE_BUILTIN_EXTENSIONS_DIR=/opt/code-server/lib/vscode/extensions
FROM glcr.b-data.ch/nodejs/nsi/${NODE_VERSION}/${BASE_IMAGE}:${BASE_IMAGE_TAG} AS nsi
......
.env:
variables:
R_VERSION: "4.4.1"
R_VERSION: "4.4.2"
TAG_VERSION_MAJ_MIN: "false"
TAG_VERSION_MAJ: "false"
......
ARG BUILD_ON_IMAGE=glcr.b-data.ch/jupyterlab/r/verse
ARG R_VERSION=4.4.2
FROM ${BUILD_ON_IMAGE}:${R_VERSION}
ARG NCPUS=1
ARG DEBIAN_FRONTEND=noninteractive
ARG BUILD_ON_IMAGE
ARG BUILD_START
ENV PARENT_IMAGE=${BUILD_ON_IMAGE}:${R_VERSION} \
BUILD_DATE=${BUILD_START}
USER root
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libfftw3-dev \
libgdal-dev \
libgeos-dev \
libgsl0-dev \
#libgl1-mesa-dev \
#libglu1-mesa-dev \
libhdf4-alt-dev \
#libhdf5-dev \
libjq-dev \
#libpq-dev \
libproj-dev \
libprotobuf-dev \
libnetcdf-dev \
#libsqlite3-dev \
#libssl-dev \
libudunits2-dev \
nco \
netcdf-bin \
postgis \
protobuf-compiler \
sqlite3 \
tk-dev \
#unixodbc-dev
&& install2.r --error --skipinstalled -n $NCPUS \
#RColorBrewer \
RNetCDF \
classInt \
deldir \
gstat \
hdf5r \
lidR \
mapdata \
mapview \
ncdf4 \
proj4 \
raster \
rlas \
sf \
sfarrow \
sp \
spacetime \
spatstat \
spatialreg \
spdep \
stars \
terra \
tidync \
tmap \
geoR \
geosphere \
## from bioconductor
&& R -e "BiocManager::install('rhdf5', update = FALSE, ask = FALSE)" \
## Strip libraries of binary packages installed from P3M
&& RLS=$(Rscript -e "cat(Sys.getenv('R_LIBS_SITE'))") \
&& strip ${RLS}/*/libs/*.so \
## Clean up
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/*
## Switch back to ${NB_USER} to avoid accidental container runs as root
USER ${NB_USER}
.env:
variables:
R_VERSION: "4.4.1"
QGIS_VERSION: "3.40.0"
R_VERSION: "4.4.2"
QGIS_VERSION: "3.42.0"
OTB_VERSION: "9.1.0"
TAG_VERSION_MAJ_MIN: "false"
TAG_VERSION_MAJ: "false"
......
ARG BASE_IMAGE=debian
ARG BASE_IMAGE_TAG=12
ARG BUILD_ON_IMAGE=glcr.b-data.ch/jupyterlab/r/geospatial
ARG R_VERSION=4.4.2
ARG QGIS_VERSION=3.42.0
ARG SAGA_VERSION
ARG OTB_VERSION
## OTB_VERSION=9.1.0
ARG PROC_SAGA_NG_VERSION
FROM ${BASE_IMAGE}:${BASE_IMAGE_TAG} AS files
ARG OTB_VERSION
ARG NB_UID=1000
ENV NB_GID=100
RUN mkdir /files
COPY conf/user /files
COPY scripts /files
RUN if [ "$(uname -m)" = "x86_64" ]; then \
## QGIS: Set OTB application folder and OTB folder
qgis3Ini="/files/var/backups/skel/.local/share/QGIS/QGIS3/profiles/default/QGIS/QGIS3.ini"; \
echo "\n[Processing]" >> ${qgis3Ini}; \
if [ -z "${OTB_VERSION}" ]; then \
echo "Configuration\OTB_APP_FOLDER=/usr/lib/otb/applications" >> \
${qgis3Ini}; \
echo "Configuration\OTB_FOLDER=/usr\n" >> ${qgis3Ini}; \
else \
echo "Configuration\OTB_APP_FOLDER=/usr/local/lib/otb/applications" >> \
${qgis3Ini}; \
echo "Configuration\OTB_FOLDER=/usr/local\n" >> ${qgis3Ini}; \
fi \
fi \
&& chown -R ${NB_UID}:${NB_GID} /files/var/backups/skel \
## Ensure file modes are correct when using CI
## Otherwise set to 777 in the target image
&& find /files -type d -exec chmod 755 {} \; \
&& find /files -type f -exec chmod 644 {} \; \
&& find /files/usr/local/bin -type f -exec chmod 755 {} \;
FROM glcr.b-data.ch/qgis/qgissi/${QGIS_VERSION}/${BASE_IMAGE}:${BASE_IMAGE_TAG} AS qgissi
FROM glcr.b-data.ch/saga-gis/saga-gissi${SAGA_VERSION:+/}${SAGA_VERSION:-:none}${SAGA_VERSION:+/$BASE_IMAGE}${SAGA_VERSION:+:$BASE_IMAGE_TAG} AS saga-gissi
FROM glcr.b-data.ch/orfeotoolbox/otbsi${OTB_VERSION:+/}${OTB_VERSION:-:none}${OTB_VERSION:+/$BASE_IMAGE}${OTB_VERSION:+:$BASE_IMAGE_TAG} AS otbsi
FROM ${BUILD_ON_IMAGE}:${R_VERSION}
ARG NCPUS=1
ARG DEBIAN_FRONTEND=noninteractive
ARG BUILD_ON_IMAGE
ARG QGIS_VERSION
ARG SAGA_VERSION
ARG OTB_VERSION
ARG PROC_SAGA_NG_VERSION
ARG BUILD_START
ENV PARENT_IMAGE=${BUILD_ON_IMAGE}:${R_VERSION} \
QGIS_VERSION=${QGIS_VERSION} \
SAGA_VERSION=${SAGA_VERSION} \
OTB_VERSION=${OTB_VERSION} \
BUILD_DATE=${BUILD_START}
USER root
ENV HOME=/root \
## GRASS GIS: Make sure the distro's python is used
GRASS_PYTHON=/usr/bin/python3
WORKDIR ${HOME}
## Install QGIS
COPY --from=qgissi /usr /usr
## Install SAGA GIS
COPY --from=saga-gissi /usr /usr
## Install Orfeo Toolbox
COPY --from=otbsi /usr/local /usr/local
ENV GDAL_DRIVER_PATH=${OTB_VERSION:+disable} \
OTB_APPLICATION_PATH=${OTB_VERSION:+/usr/local/lib/otb/applications} \
OTB_INSTALL_DIR=${OTB_VERSION:+/usr/local}
ENV OTB_APPLICATION_PATH=${OTB_APPLICATION_PATH:-/usr/lib/otb/applications} \
OTB_INSTALL_DIR=${OTB_INSTALL_DIR:-/usr}
RUN apt-get update \
&& apt-get -y install --no-install-recommends \
## Multimedia files trancoding
ffmpeg \
## QGIS: Additional runtime dependencies
'^libexiv2-[0-9]+$' \
'^libgdal[0-9]+$' \
libgeos-c1v5 \
'^libgsl[0-9]+$' \
libjs-jquery \
libjs-leaflet \
'^libprotobuf-lite[0-9]+$' \
libqca-qt5-2-plugins \
'^libqscintilla2-qt5-[0-9]+$' \
libqt5core5a \
libqt5gui5 \
libqt5keychain1 \
libqt5multimediawidgets5 \
libqt5network5 \
libqt5quickwidgets5 \
libqt5serialport5 \
libqt5sql5 \
libqt5webkit5 \
libqt5widgets5 \
libqt5xml5 \
libqwt-qt5-6 \
'^libspatialindex[0-9]+$' \
'^libzip[0-9]+$' \
ocl-icd-libopencl1 \
qt3d-assimpsceneimport-plugin \
qt3d-defaultgeometryloader-plugin \
qt3d-gltfsceneio-plugin \
qt3d-scene2d-plugin \
qt5-image-formats-plugins \
## QGIS: Python 3 Support
gdal-bin \
libfcgi0ldbl \
libsqlite3-mod-spatialite \
python3-gdal \
python3-jinja2 \
python3-lxml \
python3-matplotlib \
python3-owslib \
python3-plotly \
python3-psycopg2 \
python3-pygments \
python3-pyproj \
python3-pyqt5 \
python3-pyqt5.qsci \
python3-pyqt5.qtmultimedia \
python3-pyqt5.qtpositioning \
python3-pyqt5.qtserialport \
python3-pyqt5.qtsql \
python3-pyqt5.qtsvg \
python3-pyqt5.qtwebkit \
python3-sip \
python3-yaml \
qttools5-dev-tools \
## QGIS: Additional runtime recommendations
grass \
## QGIS: Additional runtime suggestions
gpsbabel \
## SAGA GIS: Supplementary runtime dependencies [^1]
libdxflib3 \
libhpdf-2.3.0 \
libsvm3 \
libwxgtk3.*-dev \
$(test -z "${SAGA_VERSION}" && echo "saga") \
## Orfeo Toolbox: Supplementary runtime dependencies
&& if [ "$(uname -m)" = "x86_64" ]; then \
apt-get -y install --no-install-recommends \
'^libboost-filesystem[0-9].[0-9]+.[0-9]$' \
'^libboost-serialization[0-9].[0-9]+.[0-9]$' \
libglew2.* \
'^libinsighttoolkit4.[0-9]+$' \
libmuparser2v5 \
libmuparserx4.* \
'^libopencv-core[0-9][0-9.][0-9][a-z]?$' \
'^libopencv-ml[0-9][0-9.][0-9][a-z]?$' \
libtinyxml-dev \
$(test -z "${OTB_VERSION}" && echo "otb-* monteverdi"); \
if [ ! -z "${OTB_VERSION}" ]; then \
if [ "$(echo ${OTB_VERSION} | cut -c 1)" -lt "8" ]; then \
apt-get -y install --no-install-recommends \
'^libopenthreads[0-9]+$' \
libossim1; \
fi; \
## Orfeo Toolbox: Clean up installation
bash -c 'rm -rf /usr/local/{otbenv.profile,recompile_bindings.sh,tools}'; \
if [ -f /usr/local/README ]; then \
mv /usr/local/README /usr/local/share/doc/otb; \
fi; \
if [ -f /usr/local/LICENSE ]; then \
mv /usr/local/LICENSE /usr/local/share/doc/otb; \
fi \
else \
mkdir -p /usr/lib/otb; \
ln -rs /usr/lib/$(uname -m)-linux-gnu/otb/applications \
/usr/lib/otb/applications; \
fi \
fi \
## GRASS GIS: Configure dynamic linker run time bindings
&& echo "$(grass --config path)/lib" | tee /etc/ld.so.conf.d/libgrass.conf \
&& ldconfig \
## SAGA GIS: Add en_GB.UTF-8 and update locale
&& sed -i "s/# $LANG/$LANG/g" /etc/locale.gen \
&& sed -i "s/# en_GB.UTF-8/en_GB.UTF-8/g" /etc/locale.gen \
&& locale-gen \
## [^1]: SAGA GIS: libvigraimpex11 is not available for jammy
&& if $(! grep -q "jammy" /etc/os-release); then \
apt-get -y install --no-install-recommends '^libvigraimpex[0-9]+$'; \
fi \
## Clean up
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
${HOME}/.cache \
${HOME}/.grass*
## Install QGIS related stuff
RUN apt-get update \
## Install QGIS-Plugin-Manager
&& apt-get -y install --no-install-recommends python3-pip \
&& export PIP_BREAK_SYSTEM_PACKAGES=1 \
&& /usr/bin/pip install qgis-plugin-manager \
## Install qgisprocess, the R interface to QGIS
&& install2.r --error --skipinstalled -n $NCPUS qgisprocess \
## Strip libraries of binary packages installed from P3M
&& RLS=$(Rscript -e "cat(Sys.getenv('R_LIBS_SITE'))") \
&& strip ${RLS}/*/libs/*.so \
## Clean up
&& if [ ! -z "$PYTHON_VERSION" ]; then \
apt-get -y purge python3-pip; \
apt-get -y autoremove; \
fi \
&& rm -rf /var/lib/apt/lists/* \
${HOME}/.cache \
${HOME}/.config \
${HOME}/.local
## Switch back to ${NB_USER} to avoid accidental container runs as root
USER ${NB_USER}
ENV HOME=/home/${NB_USER} \
## Qt: Support running on headless computer
QT_QPA_PLATFORM=offscreen
WORKDIR ${HOME}
## Copy files as late as possible to avoid cache busting
COPY --from=files /files /
COPY --from=files /files/var/backups/skel ${HOME}
## QGIS: Install plugin 'Processing Saga NextGen Provider'
RUN mkdir -p ${HOME}/.local/share/QGIS/QGIS3/profiles/default/python/plugins \
&& cd ${HOME}/.local/share/QGIS/QGIS3/profiles/default/python/plugins \
&& qgis-plugin-manager init \
&& qgis-plugin-manager update \
&& qgis-plugin-manager install 'Processing Saga NextGen Provider'=="${PROC_SAGA_NG_VERSION:-0.0.7}" \
## QGIS: Enable plugins
&& qgis_process plugins enable processing_saga_nextgen \
&& qgis_process plugins enable grassprovider \
&& if [ "$(uname -m)" = "x86_64" ]; then \
## QGIS: Install and enable OTB plugin
qgis-plugin-manager install 'OrfeoToolbox Provider'; \
qgis_process plugins enable orfeoToolbox_provider; \
fi \
&& rm -rf .cache_qgis_plugin_manager \
## Clean up
&& rm -rf \
${HOME}/.cache/QGIS \
${HOME}/.cache/qgis_process_ \
${HOME}/.config \
${HOME}/.grass* \
## Create backup of QGIS settings
&& cp -a ${HOME}/.local/share/QGIS /var/backups/skel/.local/share
ENV PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${OTB_VERSION:+/usr/local/lib/otb/python}
......@@ -209,15 +209,6 @@ RUN apt-get update \
&& apt-get -y install --no-install-recommends python3-pip \
&& export PIP_BREAK_SYSTEM_PACKAGES=1 \
&& /usr/bin/pip install qgis-plugin-manager \
## QGIS: Make sure qgis_mapserver and qgis_process find the qgis module
&& cp -a $(which qgis_mapserver) $(which qgis_mapserver)_ \
&& echo '#!/bin/bash' > $(which qgis_mapserver) \
&& echo "PYTHONPATH=/usr/lib/python3/dist-packages $(which qgis_mapserver)_ \"\${@}\"" >> \
$(which qgis_mapserver) \
&& cp -a $(which qgis_process) $(which qgis_process)_ \
&& echo '#!/bin/bash' > $(which qgis_process) \
&& echo "PYTHONPATH=/usr/lib/python3/dist-packages $(which qgis_process)_ \"\${@}\"" >> \
$(which qgis_process) \
## Install qgisprocess, the R interface to QGIS
&& install2.r --error --skipinstalled -n $NCPUS qgisprocess \
## Strip libraries of binary packages installed from P3M
......
.env:
variables:
R_VERSION: "4.4.1"
R_VERSION: "4.4.2"
TAG_VERSION_MAJ_MIN: "false"
TAG_VERSION_MAJ: "false"
......