
Construire des images Docker dans un pipeline (Jenkins, GitLab CI, GitHub Actions)
Apprenez comment intégrer la commande 'docker build' dans vos pipelines Jenkins, GitLab CI et GitHub Actions pour automatiser la création de vos images Docker.
L'étape 'docker build' : coeur de la CI pour les applications conteneurisées
Une fois le code source modifié et poussé sur le dépôt central, l'une des premières étapes cruciales dans un pipeline CI/CD utilisant Docker est la construction de l'image Docker. Cette image encapsule l'application et ses dépendances, devenant l'artefact qui sera ensuite testé et potentiellement déployé. Automatiser cette étape de construction (`docker build`) est donc fondamental.
La plupart des plateformes CI/CD modernes offrent des moyens d'exécuter des commandes Docker, y compris `docker build`. Que vous utilisiez Jenkins, GitLab CI, GitHub Actions, ou d'autres outils, les principes généraux restent similaires, bien que l'implémentation spécifique varie.
L'objectif est d'intégrer la construction de l'image de manière fiable et efficace dans le flux automatisé, en tirant parti des fonctionnalités de la plateforme CI/CD pour la gestion du code source, des secrets (pour l'authentification au registry) et de l'exécution des commandes.
Principes généraux de la construction d'images en CI/CD
Quelle que soit la plateforme, un job ou une étape de build Docker dans un pipeline suit généralement ces étapes :
1. Récupération du code source : Le pipeline checkout la version du code correspondant au commit ou au tag qui a déclenché le pipeline.2. Configuration de l'environnement Docker : L'agent CI doit avoir accès à un environnement Docker. Cela peut être l'agent lui-même s'il a Docker installé, un conteneur Docker dédié (Docker-in-Docker), ou via le montage du socket Docker de l'hôte.3. Authentification au Registry (si nécessaire) : Si l'image de base est privée ou si l'image construite doit être poussée vers un registry privé (ou même Docker Hub pour des dépôts privés), le pipeline doit s'authentifier en utilisant `docker login`. Les identifiants sont généralement stockés de manière sécurisée comme des secrets dans la plateforme CI/CD.4. Exécution de `docker build` : La commande `docker build` est exécutée, en utilisant le Dockerfile présent dans le dépôt. Il est essentiel de spécifier un tag approprié pour l'image construite (par exemple, basé sur le hash du commit, le tag Git, ou un numéro de version).5. Push de l'image vers un Registry : Une fois l'image construite et taguée avec succès, elle est généralement poussée (`docker push`) vers un registry central (Docker Hub, ECR, GCR, ACR, Harbor, Nexus, etc.) pour la rendre disponible pour les étapes suivantes (tests, déploiements).6. Nettoyage (optionnel) : Supprimer l'image localement sur l'agent CI pour économiser de l'espace disque.Exemples d'implémentation par plateforme
Jenkins : Jenkins utilise souvent des `Jenkinsfile` (déclaratifs ou scriptés) pour définir les pipelines. On peut exécuter des commandes Docker via des blocs `sh` ou `bat`, ou utiliser des plugins Docker dédiés (`docker-pipeline`).// Extrait simplifié d'un Jenkinsfile déclaratif
pipeline {
agent any // Ou un agent spécifique avec Docker
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build Docker Image') {
steps {
script {
// Utilisation des credentials Jenkins pour Docker Hub
withCredentials([usernamePassword(credentialsId: 'dockerhub-credentials', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh 'docker login -u $DOCKER_USER -p $DOCKER_PASS'
}
def imageName = "moncompte/monimage:${env.BUILD_NUMBER}" // Tag avec le numéro de build Jenkins
sh "docker build -t ${imageName} ."
sh "docker push ${imageName}"
}
}
}
// ... autres stages (Test, Deploy)
}
post {
always {
// Déconnexion Docker Hub
sh 'docker logout'
}
}
}GitLab CI : La configuration se fait dans le fichier `.gitlab-ci.yml`. On utilise souvent un service `docker:dind` (Docker-in-Docker) ou on configure l'exécuteur GitLab Runner pour monter le socket Docker de l'hôte. # Extrait simplifié de .gitlab-ci.yml
variables:
# Nom de l'image, $CI_REGISTRY_IMAGE est une variable prédéfinie par GitLab pointant vers le registry intégré
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
services:
- docker:dind # Utilise Docker-in-Docker
build_image:
stage: build
image: docker:latest # Utilise une image contenant le client Docker
before_script:
# Connexion au registry GitLab intégré (utilise des variables prédéfinies CI_REGISTRY_USER, CI_REGISTRY_PASSWORD, CI_REGISTRY)
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
# Possibilité d'utiliser le cache Docker de GitLab : cache: key: ... paths: - /var/lib/docker (attention aux implications)
GitHub Actions : Les workflows sont définis dans des fichiers YAML sous `.github/workflows/`. GitHub Actions propose des actions pré-construites pour simplifier les opérations Docker, comme `docker/login-action` et `docker/build-push-action`. # Extrait simplifié d'un workflow GitHub Actions
name: Build and Push Docker Image
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true # Pousse l'image après le build
tags: moncompte/monimage:latest, moncompte/monimage:${{ github.sha }} # Tag avec 'latest' et le hash du commit
Considérations clés pour le build en CI/CD
Authentification sécurisée : Ne jamais coder en dur les identifiants de registry. Utilisez les systèmes de gestion de secrets de votre plateforme CI/CD (Jenkins Credentials, GitLab CI Variables, GitHub Secrets).Gestion du cache Docker : Utiliser le cache de build Docker (`docker build --cache-from ...` ou les capacités de BuildKit) peut considérablement accélérer les builds répétitifs en CI. La mise en oeuvre dépend de la configuration de l'agent CI et de la plateforme (certaines ont des mécanismes intégrés, d'autres nécessitent une configuration manuelle, par exemple en montant un volume partagé pour le cache).Stratégie de Tagging : Adoptez une stratégie de tagging cohérente et informative. Utiliser le hash du commit (`git rev-parse --short HEAD`) ou les tags Git garantit la traçabilité entre le code source et l'image. Le tag `latest` peut être utilisé mais doit l'être avec prudence (il est mutable).BuildKit : Si possible, utilisez BuildKit (souvent activé par défaut ou via `DOCKER_BUILDKIT=1`). Il offre des builds plus rapides, une meilleure gestion du cache et des fonctionnalités avancées.Taille de l'image et sécurité : Les bonnes pratiques de construction d'images (builds multi-étapes, images de base minimales) sont encore plus importantes en CI/CD pour accélérer les pushes/pulls et réduire la surface d'attaque. Intégrez des scans de vulnérabilités (avec des outils comme Trivy, Clair, Snyk) comme étape suivant le build.Points clés du build d'images en CI/CD
L'automatisation de `docker build` est une étape centrale des pipelines CI/CD pour les applications conteneurisées. Les plateformes comme Jenkins, GitLab CI et GitHub Actions offrent toutes des mécanismes pour intégrer cette étape.
Les principes clés incluent la récupération du code, l'accès à un environnement Docker, l'authentification sécurisée au registry, l'exécution de `docker build` avec un tagging approprié, et le `docker push` de l'image résultante.
La gestion du cache Docker et l'utilisation de BuildKit sont essentielles pour optimiser les temps de build. Une stratégie de tagging rigoureuse assure la traçabilité.
Adapter l'implémentation à votre plateforme CI/CD spécifique tout en respectant ces principes généraux vous permettra de construire vos images Docker de manière fiable et efficace dans vos workflows automatisés.