Aller au contenu
CI/CD & Automatisation medium

Lab 03 — Images et runners

10 min de lecture

logo gitlab

Le pipeline fonctionne, mais il est lent et le job de build Docker échoue. Les jobs Python utilisent python:3.12, une image qui pèse plus de 900 Mo. Et le job docker-build utilise aussi une image Python — ce qui est absurde, puisqu’une image Python ne contient pas Docker. Dans ce lab, vous allez corriger ces deux problèmes en choisissant la bonne image pour chaque job.

  • Comprendre le rôle de l’image Docker dans un job GitLab CI/CD
  • Choisir entre python:3.12 et python:3.12-slim selon le contexte
  • Configurer Docker-in-Docker pour construire des images dans un pipeline
  • Lire la taille des images et mesurer l’impact sur la durée du pipeline

Chaque job GitLab CI tourne dans un conteneur Docker. Le runner télécharge l’image spécifiée, crée un conteneur, et exécute vos commandes dedans. Si l’image est lourde (900 Mo vs 150 Mo), chaque job perd du temps à la télécharger — surtout sur les runners qui ne mettent pas les images en cache entre les runs.

Situations réelles où ce lab vous aide :

  • Votre pipeline prend 8 minutes alors que les tests eux-mêmes durent 30 secondes — la majeure partie du temps est dans le pull des images
  • Un collègue a copié-collé image: python:3.12 partout sans réfléchir au choix
  • Le job de build Docker échoue avec docker: command not found — l’image utilisée ne contient pas Docker
  • Vous voulez comparer les temps de pipeline avant et après optimisation des images
  1. Passez sur la branche de départ

    Fenêtre de terminal
    cd pipeline-craft
    git checkout starter/lab-03
  2. Poussez pour déclencher le pipeline

    Fenêtre de terminal
    git push origin starter/lab-03
  3. Observez le résultat dans Build > Pipelines

    Le pipeline démarre. Les jobs ruff-lint et pytest passent — lentement. Le job docker-build échoue. C’est ce que vous allez corriger.

Regardez le .gitlab-ci.yml de la branche starter/lab-03 :

ruff-lint:
stage: lint
image: python:3.12 # ← 900+ Mo, lent à télécharger
...
pytest:
stage: test
image: python:3.12 # ← idem
...
docker-build:
stage: build
image: python:3.12 # ← ERREUR : Python ne contient pas Docker !
script:
- docker build -t pipeline-craft:test .

Il y a deux problèmes distincts.

Le premier est une question de performance : l’image python:3.12 est la version “complète” de Python, avec des compilateurs, des outils de développement système et des bibliothèques inutiles pour faire du lint ou lancer des tests. L’image python:3.12-slim est une version allégée qui contient exactement ce qu’il faut pour faire tourner Python — et rien de plus. Elle est environ 6 fois plus légère.

Le second est une erreur fonctionnelle : le job docker-build utilise image: python:3.12, une image qui contient Python et pip, mais pas la commande docker. Quand GitLab tente de lancer docker build, il obtient immédiatement sh: docker: command not found. Pour construire des images Docker dans un pipeline, il faut une image qui contient le client Docker — et un service qui fournit le daemon Docker.

  1. Ouvrez .gitlab-ci.yml dans votre éditeur

  2. Remplacez python:3.12 par python:3.12-slim dans les jobs ruff-lint et pytest

    ruff-lint:
    stage: lint
    image: python:3.12-slim # ← allégé
    before_script:
    - pip install ruff
    script:
    - ruff check app/ tests/
    pytest:
    stage: test
    image: python:3.12-slim # ← allégé
    before_script:
    - pip install -r requirements-dev.txt
    script:
    - pytest -v
  3. Corrigez le job docker-build

    Remplacez entièrement le job docker-build :

    docker-build:
    stage: build
    image: docker:27
    services:
    - docker:27-dind
    variables:
    DOCKER_TLS_CERTDIR: "/certs"
    script:
    - docker build -t pipeline-craft:test .

    Voici ce que fait chaque ligne de configuration supplémentaire :

    • image: docker:27 — cette image contient uniquement le client Docker (la commande docker). Elle est très légère (~50 Mo) et n’a pas Python.
    • services: - docker:27-dind — GitLab lance un conteneur annexe avec le daemon Docker (dockerd). C’est lui qui reçoit et exécute les commandes docker build, docker push, etc.
    • DOCKER_TLS_CERTDIR: "/certs" — le client Docker doit s’authentifier auprès du daemon via TLS. Cette variable indique où trouver les certificats que GitLab génère automatiquement.

    Sans le service dind, la commande docker build échouerait avec Cannot connect to the Docker daemon. Sans la variable TLS, la connexion échouerait pour une raison différente. Ces trois lignes forment un bloc indissociable.

stages:
- lint
- test
- build
ruff-lint:
stage: lint
image: python:3.12-slim
before_script:
- pip install ruff
script:
- ruff check app/ tests/
pytest:
stage: test
image: python:3.12-slim
before_script:
- pip install -r requirements-dev.txt
script:
- pytest -v
docker-build:
stage: build
image: docker:27
services:
- docker:27-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker build -t pipeline-craft:test .
  1. Committez et poussez

    Fenêtre de terminal
    git add .gitlab-ci.yml
    git commit -m "ci: use slim images and fix docker-build with dind"
    git push origin starter/lab-03
  2. Observez le pipeline dans Build > Pipelines

    Les trois jobs doivent passer au vert. Regardez la durée de chaque job — les jobs Python sont plus rapides qu’avant grâce aux images slim.

  • Le job ruff-lint utilise python:3.12-slim et passe au vert
  • Le job pytest utilise python:3.12-slim et passe au vert
  • Le job docker-build utilise docker:27 + service docker:27-dind et passe au vert
  • Plus d’erreur docker: command not found
ruff-lint:
image: python:3.12
image: python:3.12-slim
pytest:
image: python:3.12
image: python:3.12-slim
docker-build:
image: python:3.12
script:
- docker build -t pipeline-craft:test .
image: docker:27
services:
- docker:27-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker build -t pipeline-craft:test .
SymptômeCauseSolution
docker: command not foundImage sans Docker (ex : python:3.12) utilisée pour docker buildUtiliser image: docker:27
Cannot connect to the Docker daemonService docker:27-dind absentAjouter services: - docker:27-dind
TLS handshake errorVariable DOCKER_TLS_CERTDIR manquanteAjouter DOCKER_TLS_CERTDIR: "/certs"
pip install échoue avec -slimLe paquet nécessite un compilateur C absent des images slimUtiliser l’image complète ou ajouter apt-get install -y gcc avant pip
  • Explorez Docker Hub : toutes les images officielles expliquent la différence entre les variantes (latest, slim, alpine, bullseye…). Pour Python, consultez hub.docker.com/_/python.
  • Comparez avec solution/lab-03 : git diff starter/lab-03..solution/lab-03 montre exactement les corrections attendues.
  • Prochain level : dans le Lab 04, vous allez accélérer encore le pipeline en mettant les dépendances pip en cache pour éviter de les réinstaller à chaque run.
  • L’image Docker d’un job doit correspondre à ce que le job fait : un job Python utilise une image Python, un job de build Docker utilise une image Docker
  • Les images -slim sont 5–7x plus légères que les images complètes et suffisent dans la quasi-totalité des cas CI/CD
  • Docker-in-Docker nécessite trois éléments : image: docker:27, services: - docker:27-dind, et DOCKER_TLS_CERTDIR: "/certs" — ces trois lignes forment un bloc indissociable
  • Le choix de l’image a un impact direct sur la durée du pipeline — chaque Mo téléchargé prend du temps

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn