Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2340926
core library version updates, remove nested-dict, pin numpy and matpl…
Zeitsperre Mar 17, 2026
565bc1a
use micromamba image, move VCS tools to conda env
Zeitsperre Mar 17, 2026
4a1bb81
remove jupyter lab build command, update comments, CMD now uses micro…
Zeitsperre Mar 17, 2026
5be5022
do not install nodejs, DEBIAN_FRONTEND=noninteractive, pin intake to 2.0
Zeitsperre Mar 17, 2026
20b4ba4
use micromamba
Zeitsperre Mar 17, 2026
eb52112
release: update to use image pavics/workflow-tests:py311-260317
Zeitsperre Mar 17, 2026
9ea491e
remove plotly-dash, add exactextract and mamba, raise birdy pin
Zeitsperre Mar 18, 2026
7377969
typo fix, add requests
Zeitsperre Mar 18, 2026
3fbc508
you can do this
Zeitsperre Mar 18, 2026
985b001
release: update to use image pavics/workflow-tests:py311-260318
Zeitsperre Mar 18, 2026
2d8033a
use modern $ replacement for better shell support
Zeitsperre Mar 19, 2026
29196bc
update jupyterlab version, use python3.12, use conda-provided browse…
Zeitsperre Mar 19, 2026
b16946c
let ravenpy manage raven-hydro
Zeitsperre Mar 19, 2026
ece26fd
set workdir to /
Zeitsperre Mar 19, 2026
669fd9b
release: update to use image pavics/workflow-tests:py311-260319
Zeitsperre Mar 19, 2026
3d7cc98
rewrite Dockerfile to use mambaorg recommendations
Zeitsperre Mar 20, 2026
2d80777
release: update to use image pavics/workflow-tests:py312-260320
Zeitsperre Mar 20, 2026
d14e1a0
TEST try forcing env name
Zeitsperre Mar 20, 2026
9b2708a
TEST use args
Zeitsperre Mar 20, 2026
f63d414
split jupyter dependencies into base, no longer rely on birdy activat…
Zeitsperre Mar 20, 2026
18b4ebe
WIP - use mamba env vars, update docker-stacks scripts, add healthche…
Zeitsperre Mar 23, 2026
3a49639
drop workdir, copy env files to root dir
Zeitsperre Mar 23, 2026
0eb3c9d
recombine environment files, add openssh and jupyterlab-unfold
Zeitsperre Mar 24, 2026
acb1bb9
save build artifacts in build-src, clean tmp, set conda-forge as defa…
Zeitsperre Mar 24, 2026
5b9ec72
add hyperlinks to projects
Zeitsperre Mar 24, 2026
7068909
release: update to use image pavics/workflow-tests:py312-260324
Zeitsperre Mar 24, 2026
db20d18
re-add shell scripts
Zeitsperre Mar 24, 2026
0bd1dba
re-add PATH overrides
Zeitsperre Mar 24, 2026
84c3d03
release: update to use image pavics/workflow-tests:py312-260324-1
Zeitsperre Mar 24, 2026
4047e0f
undo PATH modification in order to try a different approach to enviro…
Zeitsperre Mar 25, 2026
4d62b0c
do not install conda in birdy environment as it takes priority over t…
Zeitsperre Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/docker-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ jobs:
set -e
echo "Running tests in Docker container"
# Run the test script inside the Docker container
conda run -n birdy mamba list
micromamba run -n birdy micromamba list
3 changes: 2 additions & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ pipeline {
// https://jenkins.io/doc/book/pipeline/syntax/
agent {
docker {
image "pavics/workflow-tests:py311-250423-update250730"
image "pavics/workflow-tests:py312-260320"
label 'linux && docker'
args "-e ENV_NAME='birdy'"
}
}

Expand Down
2 changes: 1 addition & 1 deletion binder/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM pavics/workflow-tests:py311-250423-update250730
FROM pavics/workflow-tests:py312-260320

USER root

Expand Down
151 changes: 77 additions & 74 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,90 +1,81 @@
FROM continuumio/miniconda3

# Use mamba for much improved performance over conda.
# The 'channel_priority strict' did help conda but it was not enough.
RUN conda config --prepend channels nodefaults || true && \
conda config --remove channels defaults || true && \
Comment thread
Zeitsperre marked this conversation as resolved.
conda update conda -n base && \
conda install mamba conda-pack -n base -c conda-forge && \
conda clean --all --yes && \
conda config --set channel_priority strict && \
wget -qO- https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -C /usr/local -xvj bin/micromamba

# Default for micromamba is $HOME/micromamba which is wrong.
ENV MAMBA_ROOT_PREFIX="/opt/conda"
Comment thread
Zeitsperre marked this conversation as resolved.

# to checkout other notebooks and to run pip install
# Use micromamba for improved speed and reduced image size
FROM mambaorg/micromamba
# No interactive apt calls
ENV DEBIAN_FRONTEND=noninteractive

# Install all jupyter and docker build dependencies in base
COPY environment-base.yml /tmp/environment-base.yml
RUN micromamba install --yes --name base --file /tmp/environment-base.yml && \
micromamba clean --all --yes

# Rename mambauser to jenkins for our Jenkins e2e notebooks test suite.
ARG NEW_MAMBA_USER=jenkins
ARG NEW_MAMBA_USER_ID=1000
ARG NEW_MAMBA_USER_GID=1000

USER root
# Rename mambauser to jenkins; copied from mambaorg/micromamba documentation
RUN if grep -q '^ID=alpine$' /etc/os-release; then \
# alpine does not have usermod/groupmod
apk add --no-cache --virtual temp-packages shadow; \
fi && \
usermod "--login=${NEW_MAMBA_USER}" "--home=/home/${NEW_MAMBA_USER}" \
--move-home "-u ${NEW_MAMBA_USER_ID}" "${MAMBA_USER}" && \
groupmod "--new-name=${NEW_MAMBA_USER}" \
"-g ${NEW_MAMBA_USER_GID}" "${MAMBA_USER}" && \
if grep -q '^ID=alpine$' /etc/os-release; then \
# remove the packages that were only needed for usermod/groupmod
apk del temp-packages; \
fi && \
# Update the expected value of MAMBA_USER for the
# _entrypoint.sh consistency check.
echo "${NEW_MAMBA_USER}" > "/etc/arg_mamba_user" && \
:
ENV MAMBA_USER=$NEW_MAMBA_USER

# Copy environment file
COPY --chown=$MAMBA_USER:$MAMBA_USER environment.yml /tmp/environment.yml

# Add additional fonts for matplotlib and widgets
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
git mercurial gcc unzip patch fonts-humor-sans firefox-esr x11-utils && \
Comment thread
Zeitsperre marked this conversation as resolved.
apt-get install --yes fonts-humor-sans && \
apt-get clean

# Create user jenkins for our Jenkins e2e notebooks test suite.
# Change /opt/conda folder permissions for jupyter-conda extension.
RUN groupadd --gid 1000 jenkins && \
useradd --uid 1000 --gid jenkins --shell /bin/bash --create-home jenkins && \
chmod -R a+rwX /opt/conda
Comment thread
Zeitsperre marked this conversation as resolved.

COPY environment.yml /environment.yml
Comment thread
Zeitsperre marked this conversation as resolved.

# create env "birdy"
# use umask 0000 so that the files for the new environment are usable by user 'jenkins' for the jupyter-conda-extension
#
# Perform 2 stages install because one single 'conda env create -f
# /environment.yml' was taking forever to complete, same with mamba.
# Had to do this 2 stages install. 2 stages install was also taking forever
# with conda so had to switch to mamba.
#
# One single 'conda env create -f /environment.yml' takes forever because we
# Perform two-stage install because one single 'conda env create -f /environment.yml'
# was taking forever to complete, same with mamba.
# Previously, one single 'conda env create -f /environment.yml' took forever because we
# removed all direct dependencies of xclim and ravenpy in /environment.yml for
# dependencies pinning by xclim and ravenpy to take effect. This results in
# conda having a lot more packages to "solve" and it seems the solver
# dependencies pinning by xclim and ravenpy to take effect.
# This resulted in conda having a lot more packages to "solve" and it seems the solver
# performance dropped exponentially with the number of packages to solve.
#
# Conda was stuck at this step:
# DEBUG conda.common._logic:_run_sat(607): Invoking SAT with clause count: 2500273
#
# As of March 2026, the new image uses mambaorg/micromamba and the libmamba solver by default.

# Create birdy environment
RUN umask 0000 && \
mamba create --name birdy --channel conda-forge python=3.11 clisops figanos ravenpy xclim xscen xsdba --yes && \
(conda env export --name birdy 2>&1 | tee /conda-env-export-phase1.yml) && \
(du -sh /opt/conda 2>&1 | tee /conda-envs-size-phase1.txt) && \
mamba env update --name birdy --file /environment.yml && \
mamba clean --all --yes

# alternate way to 'source activate birdy'
ENV PATH="/opt/conda/envs/birdy/bin:$PATH"

# our notebooks are hardcoded to lookup for kernel named 'birdy'
# this python is from the birdy env above
RUN python -m ipykernel install --name birdy && \
(conda env export --name birdy 2>&1 | tee /conda-env-export-final.yml) && \
(diff --unified /conda-env-export-phase1.yml /conda-env-export-final.yml 2>&1 | tee /conda-env-export.diff) && \
(du -sh /opt/conda 2>&1 | tee /conda-envs-size-final.txt) && \
diff /conda-envs-size-phase1.txt /conda-envs-size-final.txt || true

# install using same channel preferences as birdy original env to not downgrade anything accidentally
# this is for debug only, all dependencies should be specified in environment.yml above
# RUN mamba install -c conda-forge -c cdat -c bokeh -c fortiers -n birdy nbdime

# build jupyterlab extensions installed by conda, see `jupyter labextension list`
# Supposedly not needed with jupyterlab v3 anymore but see
# https://github.com/jupyterlab/jupyterlab/issues/11726#issuecomment-998901247
# TODO: remove 'jupyter lab build' step once all extensions move to prebuilt extensions,
# see comment https://github.com/jupyterlab/jupyterlab/issues/11726#issuecomment-998917305
# Currently jupyter-dash is holding back this step, see
# https://github.com/plotly/jupyter-dash/issues/49
Comment thread
Zeitsperre marked this conversation as resolved.
RUN jupyter lab build

RUN jupyter serverextension enable voila --sys-prefix && \
jupyter serverextension enable panel.io.jupyter_server_extension --sys-prefix && \
Comment thread
Zeitsperre marked this conversation as resolved.
jupyter serverextension list
# jupyter labextension install jupyterlab-clipboard
micromamba create --name birdy --file /tmp/environment.yml "python>=3.12,<3.13" --yes && \
micromamba clean --all --yes

# Notebooks are hardcoded to lookup for kernel named 'birdy' created in the previous code block
RUN umask 0000 && \
micromamba run --name birdy python -m ipykernel install --name birdy && \
micromamba env export --name birdy | tee /conda-env-export-final.yml && \
du -sh /opt/conda | tee /conda-envs-size-final.txt

# This should be "master" but commit
# https://github.com/jupyter/docker-stacks/commit/c772e98ac794173d6ed83a08ec249038b27ca3be
# is breaking with us since we do not have user jovyan.
ENV DOCKER_STACKS_COMMIT=709206ac8788475728cc9c992c25fb5f1501bc29

# Activate base environment
ARG MAMBA_DOCKERFILE_ACTIVATE=1

# /notebook_dir for Pavics-landing notebooks to re-create Jupyter env layout:
# /notebook_dir/writable-workspace, /notebook_dir/pavics-homepage.
#
Expand All @@ -101,14 +92,17 @@ RUN wget https://raw.githubusercontent.com/jupyter/docker-stacks/$DOCKER_STACKS_
chmod a+rx /usr/local/bin/start.sh /usr/local/bin/start-singleuser.sh /usr/local/bin/start-notebook.sh /usr/local/bin/fix-permissions && \
chmod a+r /etc/jupyter/jupyter_notebook_config.py && \
mkdir -p /notebook_dir/writable-workspace && \
chown jenkins /notebook_dir/writable-workspace && \
chown "${MAMBA_USER}" /notebook_dir/writable-workspace && \
mkdir -p /notebook_dir/pavics-homepage && \
chown jenkins /notebook_dir/pavics-homepage && \
chown "${MAMBA_USER}" /notebook_dir/pavics-homepage && \
chown root:root /notebook_dir && \
chmod a-w /notebook_dir && \
mkdir -p /opt/conda/envs/birdy/fonts && \
Comment thread
Zeitsperre marked this conversation as resolved.
Outdated
chmod a+rwX -R /opt/conda/envs/birdy/fonts && \
mkdir /opt/conda/pkgs/cache && \
chown jenkins:jenkins -R /opt/conda/pkgs/cache && \
mkdir -p /opt/conda/pkgs/cache && \
chown "${MAMBA_USER}":"${MAMBA_USER}" -R /opt/conda/pkgs/cache && \
touch /opt/conda/pkgs/pkgs.lock && \
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh, you have to create a "lock" file??? Should't let the installer do it and clean up after itself?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was making this file and giving write permissions to the user in advance. It only gets created IFF the user runs conda or mamba.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only gets created IFF the user runs conda or mamba.

That's it, so the lock file should be created Only IF the user runs conda or mamba. Creating it in advance in the image like this is wrong no?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because we're creating it with the proper privileges. We don't need the user to have ownership over the folder if they already have access to the relevant files within it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out this is irrelevant: We're giving jenkins access to these folders by default. I'll keep this for good measure though.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain the reason to have this lock file /opt/conda/pkgs/pkgs.lock pre-created? What bug or error you are trying to fix? Intuitively it looks weird to have a pre-existing lock file. Looking at the commit that introduced that lock file 3d7cc98, it is not explained.

chown "${MAMBA_USER}":"${MAMBA_USER}" /opt/conda/pkgs/pkgs.lock && \
mkdir -p /usr/local/bin && \
wget https://downloads.globus.org/globus-connect-personal/linux/stable/globusconnectpersonal-latest.tgz -O /usr/local/bin/globusconnectpersonal-latest.tgz && \
tar xzf /usr/local/bin/globusconnectpersonal-latest.tgz -C /usr/local/bin/ && \
Expand All @@ -118,6 +112,10 @@ RUN wget https://raw.githubusercontent.com/jupyter/docker-stacks/$DOCKER_STACKS_
# For jupyter-panel-proxy launcher.
ENV BOKEH_ALLOW_WS_ORIGIN="*"

# To supply the location of the RavenHydroFramework binary
# FIXME: This location should be provided via the raven-hydro package which would help with the discovery logic in RavenPy
ENV RAVENPY_RAVEN_BINARY_PATH="/opt/conda/envs/birdy/bin/raven"

# For import xesmf since esmf-8.4.0, see: https://github.com/conda-forge/esmf-feedstock/issues/91
ENV ESMFMKFILE="/opt/conda/envs/birdy/lib/esmf.mk"

Expand All @@ -130,10 +128,15 @@ ENV gcc=x86_64-conda-linux-gnu-gcc
ENV g++=x86_64-conda-linux-gnu-g++
ENV gfortran=x86_64-conda-linux-gnu-gfortran

# JupyterLab cannot write to hidden folders by design
ENV XDG_CACHE_HOME="/home/${MAMBA_USER}/cache"
Comment thread
Zeitsperre marked this conversation as resolved.

# problem running start-notebook.sh when being root
# the jupyter/base-notebook image also do not default to root user so we do the same here
USER jenkins
USER $MAMBA_USER
# set entrypoint for jenkins to root
WORKDIR /
Comment thread
Zeitsperre marked this conversation as resolved.
Outdated

# follow jupyter/base-notebook image so config in jupyterhub is simpler
# start notebook in conda environment to have working jupyter extensions
CMD ["conda", "run", "-n", "birdy", "/usr/local/bin/start-notebook.sh"]
CMD ["/usr/local/bin/_entrypoint.sh", "run", "/usr/local/bin/start-notebook.sh"]
Comment thread
Zeitsperre marked this conversation as resolved.
94 changes: 94 additions & 0 deletions docker/environment-base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# conda env create -f environment.yml
Comment thread
Zeitsperre marked this conversation as resolved.
Outdated
name: base
channels:
- conda-forge
dependencies:
# UTILITIES

# conda: a cross-platform, language-agnostic binary package manager
# NOTE: Included as a requirement for gator
# https://github.com/conda/conda
- conda >= 4.7.12
# git: fast, scalable, distributed revision control system
# NOTES: Included as a requirement for jupyterlab-git
- git
# mamba: a reimplementation of the conda package manager in C++
# NOTE: Included as a requirement for gator
# https://github.com/mamba-org/mamba
- mamba >= 2.0
# wget: command-line utility for downloading files from the web
- wget

# JUPYTER LIBRARIES

# Jupyter conda metapackage: Install all the Jupyter components in one go.
# https://anaconda.org/conda-forge/jupyter
- jupyter
# notebook: A web-based notebook environment for interactive computing.
# to be launched by image jupyterhub/jupyterhub
# https://github.com/jupyter/notebook
- notebook
# jupyterlab: An extensible environment for interactive and reproducible computing
# https://github.com/jupyterlab/jupyterlab
- jupyterlab >= 4.0
# JupyterHub: A multi-user server for Jupyter notebooks
# https://github.com/jupyterhub/jupyterhub
- jupyterhub
# ipywidgets: Interactive HTML Widgets
# https://github.com/jupyter-widgets/ipywidgets
# https://ipywidgets.readthedocs.io/en/latest/user_install.html
- ipywidgets
# ipyleaflet: A Jupyter / Leaflet bridge enabling interactive maps in the Jupyter notebook.
# https://github.com/jupyter-widgets/ipyleaflet
- ipyleaflet
# gator: The Mamba Navigator, a Web UI for managing conda environments
# https://github.com/mamba-org/gator
- mamba_gator
# nbdime: Jupyter Notebook Diff and Merge tools
# https://github.com/jupyter/nbdime
- nbdime
# jupyter_bokeh: An extension for rendering Bokeh content in JupyterLab notebooks
# https://github.com/bokeh/jupyter_bokeh
- jupyter_bokeh
# jupytext: extension to produce .py files from notebook .ipynb files
# https://github.com/mwouts/jupytext
- jupytext
# jupyterlab-git: A JupyterLab extension for version control using Git
# https://github.com/jupyterlab/jupyterlab-git
- jupyterlab-git >= 0.44.0
# voila: Voilà turns Jupyter notebooks into standalone web applications
# https://github.com/voila-dashboards/voila
- voila
# jupyterlab-archive: A Jupyter extension to make, download and extract archive files.
# https://github.com/jupyterlab-contrib/jupyter-archive
- jupyter-archive
# jupyter-resource-usage: Jupyter Extension to show resource usage
# https://github.com/jupyter-server/jupyter-resource-usage
# migrated from https://github.com/jtpio/jupyterlab-system-monitor and originally from jupyterlab-topbar
- jupyter-resource-usage
# xeus-python: back-end kernel implementing the Jupyter Debug Protocol
# https://github.com/jupyter-xeus/xeus-python
- xeus-python
# jupyter-server-proxy: run arbitrary external processes alongside your notebook server
# https://github.com/jupyterhub/jupyter-server-proxy
- jupyter-server-proxy
# dask-labextension: A JupyterLab extension for Dask.
# https://github.com/dask/dask-labextension
- dask-labextension
# jupyterlab-geojson: JupyterLab extension for rendering GeoJSON
# https://github.com/jupyterlab/jupyter-renderers/tree/main/packages/geojson-extension
- jupyterlab-geojson
# jupyterlab-topbar: JupyterLab Top Bar Extensions
# https://github.com/jtpio/jupyterlab-topbar
- pip:
- jupyterlab-logout >= 1.1.0
- jupyterlab-theme-toggler >= 1.1.0

# BROWSER SUPPORT

# firefox: The one and only
# https://github.com/mozilla-firefox/firefox
- firefox
# selenium: Python library for automating web browser interaction
# https://github.com/SeleniumHQ/Selenium
- selenium
Loading
Loading