Skip to content
Snippets Groups Projects
Verified Commit 8f7e780e authored by Olivier Benz's avatar Olivier Benz
Browse files

Freeze Python v3.13.1

parent c99e642b
Branches freeze-version
No related tags found
No related merge requests found
......@@ -45,7 +45,7 @@ Topmost entry = Tag `latest`
| Python | CTAN date | Quarto |
|:-----------|:-----------|:------------|
| 3.13.1[^1] | | 1.6.40 |
| 3.13.1 | 2025‑02‑04 | 1.6.40 |
| 3.12.9 | | 1.6.40 |
| 3.12.8 | 2025‑02‑04 | 1.6.40 |
| 3.13.0[^1] | 2024‑12‑03 | 1.6.39 |
......
.env:
variables:
PYTHON_VERSION: "3.12.9"
TAG_VERSION_MAJ_MIN: "true"
PYTHON_VERSION: "3.13.1"
TAG_VERSION_MAJ_MIN: "false"
TAG_VERSION_MAJ: "false"
.before-script-build: &before-script-build
......
ARG BASE_IMAGE=debian
ARG BASE_IMAGE_TAG=12
ARG BUILD_ON_IMAGE=glcr.b-data.ch/python/ver
ARG PYTHON_VERSION=3.13.1
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.96.4
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}${PYTHON_VERSION:+:}${PYTHON_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR} AS files
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/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 \
&& if [ -n "${CUDA_VERSION}" ]; then \
## 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 \
## 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}${PYTHON_VERSION:+:}${PYTHON_VERSION}${CUDA_IMAGE_FLAVOR:+-}${CUDA_IMAGE_FLAVOR}
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/python/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}${PYTHON_VERSION:+:}${PYTHON_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
## 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; \
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 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] \
## 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
## 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"]
ARG BASE_IMAGE=debian
ARG BASE_IMAGE_TAG=12
ARG BUILD_ON_IMAGE
ARG PYTHON_VERSION=3.13.1
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}${PYTHON_VERSION:+:}${PYTHON_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}${PYTHON_VERSION:+:}${PYTHON_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}
.env:
variables:
PYTHON_VERSION: "3.12.9"
PYTHON_VERSION: "3.13.1"
CTAN_REPO_BUILD_LATEST: "https://mirror.init7.net/ctan/systems/texlive/tlnet"
TAG_VERSION_MAJ_MIN: "true"
TAG_VERSION_MAJ_MIN: "false"
TAG_VERSION_MAJ: "false"
.before-script-build: &before-script-build
......
ARG BUILD_ON_IMAGE=glcr.b-data.ch/jupyterlab/python/base
ARG PYTHON_VERSION=3.13.1
ARG CODE_BUILTIN_EXTENSIONS_DIR=/opt/code-server/lib/vscode/extensions
ARG QUARTO_VERSION=1.6.40
ARG CTAN_REPO=https://www.texlive.info/tlnet-archive/2025/02/04/tlnet
FROM ${BUILD_ON_IMAGE}${PYTHON_VERSION:+:}${PYTHON_VERSION}
ARG DEBIAN_FRONTEND=noninteractive
ARG BUILD_ON_IMAGE
ARG CODE_BUILTIN_EXTENSIONS_DIR
ARG QUARTO_VERSION
ARG CTAN_REPO
ARG CTAN_REPO_BUILD_LATEST
ARG BUILD_START
USER root
ENV PARENT_IMAGE=${BUILD_ON_IMAGE}${PYTHON_VERSION:+:}${PYTHON_VERSION} \
QUARTO_VERSION=${QUARTO_VERSION} \
BUILD_DATE=${BUILD_START}
ENV HOME=/root \
PATH=/opt/TinyTeX/bin/linux:/opt/quarto/bin:$PATH
WORKDIR ${HOME}
RUN dpkgArch="$(dpkg --print-architecture)" \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
fonts-roboto \
ghostscript \
librsvg2-bin \
qpdf \
texinfo \
## Python: For h5py wheels (arm64)
libhdf5-dev \
## Install quarto
&& curl -sLO https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-${dpkgArch}.tar.gz \
&& mkdir -p /opt/quarto \
&& tar -xzf quarto-${QUARTO_VERSION}-linux-${dpkgArch}.tar.gz -C /opt/quarto --no-same-owner --strip-components=1 \
&& rm quarto-${QUARTO_VERSION}-linux-${dpkgArch}.tar.gz \
## Exempt quarto from address space limit
&& sed -i 's/"${QUARTO_DENO}"/prlimit -v=unlimited: "${QUARTO_DENO}"/g' \
/opt/quarto/bin/quarto \
## Remove quarto pandoc
&& rm /opt/quarto/bin/tools/$(uname -m)/pandoc \
## Link to system pandoc
&& ln -s /usr/bin/pandoc /opt/quarto/bin/tools/$(uname -m)/pandoc \
## Tell APT about the TeX Live installation
## by building a dummy package using equivs
&& apt-get install -y --no-install-recommends equivs \
&& cd /tmp \
&& wget https://github.com/scottkosty/install-tl-ubuntu/raw/master/debian-control-texlive-in.txt \
&& equivs-build debian-* \
&& mv texlive-local*.deb texlive-local.deb \
&& dpkg -i texlive-local.deb \
&& apt-get -y purge equivs \
&& apt-get -y autoremove \
## Admin-based install of TinyTeX
&& CTAN_REPO_ORIG=${CTAN_REPO} \
&& CTAN_REPO=${CTAN_REPO_BUILD_LATEST:-$CTAN_REPO} \
&& export CTAN_REPO \
&& wget -qO- "https://yihui.org/tinytex/install-unx.sh" \
| sh -s - --admin --no-path \
&& mv ${HOME}/.TinyTeX /opt/TinyTeX \
&& sed -i "s|${HOME}/.TinyTeX|/opt/TinyTeX|g" \
/opt/TinyTeX/texmf-var/fonts/conf/texlive-fontconfig.conf \
&& ln -rs /opt/TinyTeX/bin/$(uname -m)-linux \
/opt/TinyTeX/bin/linux \
&& /opt/TinyTeX/bin/linux/tlmgr path add \
&& tlmgr update --self \
## TeX packages as requested by the community
&& curl -sSLO https://yihui.org/gh/tinytex/tools/pkgs-yihui.txt \
&& tlmgr install $(cat pkgs-yihui.txt | tr '\n' ' ') \
&& rm -f pkgs-yihui.txt \
## TeX packages as in rocker/verse
&& tlmgr install \
context \
pdfcrop \
## TeX packages as in jupyter/scipy-notebook
&& tlmgr install \
cm-super \
dvipng \
## TeX packages specific for nbconvert
&& tlmgr install \
oberdiek \
titling \
&& tlmgr path add \
&& tlmgr option repository ${CTAN_REPO_ORIG} \
&& chown -R root:${NB_GID} /opt/TinyTeX \
&& chmod -R g+w /opt/TinyTeX \
&& chmod -R g+wx /opt/TinyTeX/bin \
## Make the TeX Live fonts available as system fonts
&& cp /opt/TinyTeX/texmf-var/fonts/conf/texlive-fontconfig.conf \
/etc/fonts/conf.d/09-texlive.conf \
&& fc-cache -fsv \
## Install Python packages
&& export PIP_BREAK_SYSTEM_PACKAGES=1 \
&& pip install \
altair \
beautifulsoup4 \
bokeh \
bottleneck \
cloudpickle \
cython \
dask \
dill \
h5py \
ipympl\
ipywidgets \
matplotlib \
numba \
numexpr \
numpy \
pandas \
patsy \
protobuf \
scikit-image \
scikit-learn \
scipy \
seaborn \
sqlalchemy \
statsmodels \
sympy \
tables \
widgetsnbextension \
xlrd \
## Install facets
&& cd /tmp \
&& git clone https://github.com/PAIR-code/facets.git \
&& jupyter nbclassic-extension install facets/facets-dist/ --sys-prefix \
&& cd / \
## Install code-server extensions
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension quarto.quarto \
&& code-server --extensions-dir ${CODE_BUILTIN_EXTENSIONS_DIR} --install-extension James-Yu.latex-workshop \
## Update default PATH settings in /etc/profile.d/00-reset-path.sh
&& sed -i 's|/opt/code-server/bin|/opt/TinyTeX/bin/linux:/opt/quarto/bin:/opt/code-server/bin|g' /etc/profile.d/00-reset-path.sh \
## Clean up
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
${HOME}/.cache \
${HOME}/.config \
${HOME}/.local \
${HOME}/.wget-hsts
## Switch back to ${NB_USER} to avoid accidental container runs as root
USER ${NB_USER}
ENV CTAN_REPO=${CTAN_REPO}
ENV HOME=/home/${NB_USER}
WORKDIR ${HOME}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment