Notebook et programmation lettrée
  • Code source
  • Ouvrir une issue
  1. Pour aller plus loin…
  2. CI/CD avancé
  • Pratique individuelle
    • Introduction
      • Présentation
      • Environnement
      • Données
    • Notebook
      • Opt1 - Quarto + R
      • Opt2 - Jupyter + Python
    • Forge logicielle
      • Création dépôt
      • CI/CD
      • .gitignore
  • Pratique collective
    • Présentation
    • Environnement
    • Exercice
  • Pour aller plus loin…
    • CI/CD avancé
    • Environnements virtuels
  1. Pour aller plus loin…
  2. CI/CD avancé

Déploiement continu (avancé)

Il y a plusieurs possibilités qui dépendent aussi de vos objectifs vis à vis du déploiement, et les critères peuvent être nombreux :

  • simplicité d’usage : image déjà packagé par une équipe ou distributio nue ?
  • rapidité du déploiement : compilation des sources ou binaires ?
  • reproductibilité : Ubuntu LTS ou Debian Unstable ?
  • taille de l’image ?
  • etc :

Dans la partie CI/CD nous avons vu la version simple, rapide, efficace, presque … magique.

Toutefois, pour des raisons diverses et variées vous pouvez être amené(e)s un jour à déployer vos propres recettes de CI/CD pour des Notebooks.

Voici quelques pistes de recettes supplémentaires.

From Scratch, ou presque…

  • R & Quarto
  • Python & Jupyter

Pour garder les mains libre (pas de RStudio, de Posit intégré à l’image par exemple), et avoir le maximum de liberté et de flexibilité, alors il est possible de partir d’une image de distribution nue.

Astuce

Toutes les recettes Dockerfile sont ici si vous voulez vous en inspirer : https://github.com/rocker-org/rocker-versioned2/tree/master/dockerfiles

Si vous vous sentez concerné par la reproductibilité future de votre workflow, alors une Debian est tout indiqué, ne serait ce que pour les efforts réalisés par l’équipe ces dernières années au sein du consortium Reproducible Builds

Il est possible de partir d’une image Debian et d’installer au dessus la version de R qui vous convient. Vous trouverez de la documentation sur le CRAN à ce sujet.

Il faudra, au moins la première fois, s’armer de patience car la compilation des packages R peut être longue. Seules les fonctionnalités de cache propre au CI vous permettront de gagner du temps.

image: debian:bookworm-20250610-slim

variables:
  QUARTO_VERSION: 1.8.2

before_script:
   - export LC_ALL=C.UTF-8
   - apt-get update && apt-get install -y apt-transport-https curl wget libcurl4-gnutls-dev libudunits2-dev git pandoc libgdal-dev libproj-dev libgeos-dev proj-bin geos-bin gdal-bin libabsl-dev libfontconfig1-dev cmake libharfbuzz-dev libfribidi-dev  
  - apt-get install -y dirmngr --install-recommends
  - cat cran40.pub | tee /etc/apt/trusted.gpg.d/cran_debian_key.asc
  - echo "deb http://cloud.r-project.org/bin/linux/debian bookworm-cran40/" | tee -a /etc/apt/sources.list
  - apt-get update && apt-get install r-base
  - wget "https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.deb"
  - dpkg -i quarto-${QUARTO_VERSION}-linux-amd64.deb 
  - R -e "install.packages(c('quarto', 'sf', 'tidygeocoder', 'mapview', 'osrm', 'DT'))"
 
pages:
  script:
    - rm -rf index_files/  index.html
   - R -e "install.packages('quarto')"
    - quarto render index.qmd
    - mv -v img public/
    - mv -v *.html public/
    - mv -v index_files public/
  artifacts:
    paths:
      - public
  only:
    - main

Pour que le cache soit effectif, il y a quelques modifications à faire dans le fichier gitlab-ci.yml :

image: debian:bookworm-20250610-slim

variables:
  QUARTO_VERSION: 1.8.2
  R_LIBS_USER: "$CI_PROJECT_DIR/ci/lib"
  BUILD_LOGS_DIR: "$CI_PROJECT_DIR/ci/logs/"

before_script:
  - export LC_ALL=C.UTF-8
  - apt-get update && apt-get install -y apt-transport-https curl wget libcurl4-gnutls-dev libudunits2-dev git pandoc libgdal-dev libproj-dev libgeos-dev proj-bin geos-bin gdal-bin libabsl-dev libfontconfig1-dev cmake libharfbuzz-dev libfribidi-dev
  - apt-get install -y dirmngr --install-recommends
  - cat cran40.pub | tee /etc/apt/trusted.gpg.d/cran_debian_key.asc
  - echo "deb http://cloud.r-project.org/bin/linux/debian bookworm-cran40/" | tee -a /etc/apt/sources.list
  - apt-get update && apt-get install -y r-base
  - mkdir -p $R_LIBS_USER $BUILD_LOGS_DIR
  - echo "R_LIBS='$R_LIBS_USER'" > .Renviron
  - wget "https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.deb"
  - dpkg -i quarto-${QUARTO_VERSION}-linux-amd64.deb
  - R -e "install.packages(c('quarto', 'sf', 'tidygeocoder', 'mapview', 'osrm', 'DT'))"

pages:
  script:
    - rm -rf index_files/ index.html
    - quarto render index.qmd --log-level debug
    - mv -v img public/
    - mv -v *.html public/
    - mv -v index_files public/
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
    - $R_LIBS_USER

  artifacts:
    paths:
      - public
  only:
    - main

C’est la recette équivalente à l’image “maison” que j’ai réalisé pour simplifier le déploiement de mon super notebook python

image: python:3.10-slim-bookworm
pages:
  before_script:
    - apt-get update && apt-get -y install curl gdal-bin libgdal-dev geos-bin libgeos-dev proj-bin libproj-dev python3-numpy >
    - python -m venv .venv # Create virtual environment inside the .venv directory
    - source .venv/bin/activate  # Activate the environment
    - pip install --upgrade pip
    - pip install pip-tools
    - pip-compile requirements.in
    - pip-sync requirements.txt
  script:
  - export BASE_URL="$CI_PAGES_URL"
  - export JUPYTER_BASE_URL="http://127.0.0.1:8888"
  - export JUPYTER_TOKEN="montokenrandom"
  - jupyter server --IdentityProvider.token='montokenrandom' --notebook-dir="$(pwd)" --Serv>
  - jupyter-book build -d --execute --html
  - mkdir .public
  - cp -r _build/html/* .public
  - mv .public public
  - echo "Votre document a été déployé à ce lien $CI_PAGES_URL"
  artifacts:
    paths:
    - public
  only:
  - main

Le Dockerfile ayant servi à la construction est reproduit ici, mais vous pouvez le trouver aussi dans le dépot avec le matériel supplémentaire :

1FROM python:3.10-slim-bookworm

MAINTAINER Sebastien Rey-Coyrehourcq <sebastien.rey-coyrehourcq@univ-rouen.fr>

RUN apt-get update && apt-get install --no-install-recommends -y curl gdal-bin libgdal-dev geos-bin libgeos-dev proj-bin \
libproj-dev python3-numpy gcc g++ make nodejs texlive-latex-base latexmk wget npm net-tools gosu graphviz bash webp

2ARG DOCKER_USER=myst-user

RUN wget -c https://github.com/nicolas-van/multirun/releases/download/1.1.3/multirun-x86_64-linux-gnu-1.1.3.tar.gz -O - | tar -xz
3RUN mv multirun /bin

4RUN useradd -ms /bin/bash "$DOCKER_USER"
USER "$DOCKER_USER"
WORKDIR /home/"$DOCKER_USER"

ENV PATH="/home/myst-user/.local/bin:$PATH" 

5COPY requirements.in .

RUN pip install --upgrade pip
RUN pip install --user pip-tools
RUN pip-compile requirements.in
RUN pip-sync requirements.txt
RUN pip install --user --no-cache-dir -r requirements.txt

RUN pip install numpy
RUN pip install gdal==$(gdal-config --version)

COPY docker-entrypoint.sh .

6RUN sed "s/\$DOCKER_USER/$DOCKER_USER/g" -i docker-entrypoint.sh
RUN chmod 755 docker-entrypoint.sh

7WORKDIR /home/"$DOCKER_USER"

8ENTRYPOINT ["sh", "docker-entrypoint.sh"]
9CMD ["multirun", "jupyter-lab --IdentityProvider.token='512ac78f14e1141db1fac17e8b4099c1e5bc7d589518b38c' --ServerApp.allow_origin='http://localhost:3000' --ip=0.0.0.0 --port 8888 --no-browser &"]
1
L’image de référence utilisé
2
Au cas ou on aurait besoin de lancer plusieurs services dans le même container
3
Dans les bonnes pratique il est recommandé d’utiliser Docker en mode utilisateur et non pas en root, c’est pourquoi on définit un utilisateur myst-user qui va être utilisé tout au long du Dockerfile.
4
Commande pour créer l’utilisateur myst-user au sein de l’image
5
On copie le fichier Requirements python qui contient les dépendances nécessaire à Jupyter Lab
6
Le fichier docker-entrypoint.sh contient le script qui permet de lancer les futures commandes qui seront passés lors du docker run avec l’utilisateur myst-user dans le container
7
Le répertoire par défaut pour l’utilisateur sera /home/myst-user
8
Le point de passage de toutes les commandes futures
9
La commande lancé par défaut, lorsque le container est lancé, même sans argument autre est le serveur Jupyter Lab
 

Produit par le GT Notebook avec Quarto - 2025