Aller au contenu principal

CI/CD avec Docker

Automatiser le déploiement d'applications avec des conteneurs

attention

Il est recommandé de consulter la documentation officielle de Docker et celle de GitHub Actions pour des informations à jour.

Notions théoriques

Le CI/CD (Intégration Continue / Déploiement Continu) est un ensemble de pratiques visant à automatiser les étapes de développement, de test et de déploiement d'une application.

astuce

Docker permet de faciliter cette automatisation grâce à la conteneurisation des applications.

Intégration continue (CI)

L'intégration continue consiste à tester automatiquement le code à chaque modification. L'objectif est de détecter rapidement les erreurs et de garantir que l'application reste fonctionnelle au fil des versions.

Les étapes typiques de la CI sont :

  • Récupérer le code depuis un dépôt (par exemple sur GitHub)
  • Installer les dépendances
  • Lancer les tests automatiques
  • Construire une image Docker

Déploiement continu (CD)

Le déploiement continu consiste à livrer automatiquement une nouvelle version de l'application après validation. Cela peut inclure :

  • Pousser l'image Docker sur un registre (Docker Hub, GitHub Container Registry…)
  • Déployer l'image sur un serveur de production ou de test

Pourquoi utiliser Docker dans un pipeline CI/CD

Docker permet de :

  • Garantir que l’environnement d’exécution est identique en local, en test et en production
  • Automatiser la construction et le déploiement des applications
  • Réduire les erreurs liées aux différences de configuration

Outils courants

  • GitHub Actions : permet de définir des workflows d’automatisation directement dans un dépôt GitHub
  • Docker Hub : registre d’images Docker
  • GitLab CI/CD : alternative à GitHub Actions, intégrée à GitLab
  • Travis CI, CircleCI, Jenkins : autres outils CI/CD

Fichier de configuration .github/workflows/

Un workflow GitHub Actions est défini dans un fichier YAML. Il contient :

  • Des déclencheurs (on: push, on: pull_request, etc.)
  • Des jobs (unités d'exécution)
  • Des steps (étapes à exécuter dans chaque job)

Exemple de structure :

name: CI

on:
push:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t mon-image .

Bonnes pratiques

  • Versionner les images Docker (éviter le tag latest)
  • Utiliser des secrets pour les identifiants (Docker Hub, SSH, etc.)
  • Scanner les images Docker pour détecter les vulnérabilités
  • Nettoyer les ressources inutiles après le build
  • Utiliser des images légères (ex : python:3.11-slim)

Exemple pratique

Il est possible de configurer un pipeline CI/CD avec GitHub Actions pour construire une image Docker à chaque push sur la branche main, puis la publier sur Docker Hub.

Étapes

  1. Créer un projet contenant un fichier app.py :
print("Application CI/CD avec Docker")
  1. Créer un Dockerfile :
FROM python:3.11-slim

WORKDIR /app
COPY app.py .

CMD ["python", "app.py"]
  1. Créer un fichier .github/workflows/docker.yml :
name: Build and Push Docker Image

on:
push:
branches:
- main

jobs:
docker:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Login to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

- name: Build image
run: docker build -t mon-utilisateur/mon-image:latest .

- name: Push image
run: docker push mon-utilisateur/mon-image:latest
  1. Ajouter les secrets DOCKER_USERNAME et DOCKER_PASSWORD dans les paramètres du dépôt GitHub

  2. Pousser le projet sur GitHub

À chaque git push sur main, GitHub Actions construit et publie l’image sur Docker Hub.

Test de mémorisation/compréhension


Quel est le rôle principal de l'intégration continue (CI) ?


Quel outil est utilisé pour configurer un workflow sur GitHub ?


Quel est le déclencheur pour lancer un workflow à chaque push ?


Quelle commande permet de construire une image Docker ?


Quel mot-clé est utilisé pour exécuter un job sur Ubuntu ?


Quel fichier contient la configuration d’un pipeline GitHub Actions ?


Pourquoi utiliser un tag explicite pour une image Docker ?


Que permet la commande docker push ?


Quel est l’intérêt d’utiliser une image slim ?


Où configurer les secrets dans un dépôt GitHub ?



TP pour réfléchir et résoudre des problèmes

Créer un pipeline CI/CD pour une API Flask avec Docker et GitHub Actions

Ce TP consiste à créer une API web simple avec Flask, à la conteneuriser avec Docker, puis à configurer un pipeline CI/CD avec GitHub Actions pour construire et publier l’image Docker sur Docker Hub à chaque modification du code.

Étape 1 — Créer une API Flask minimaliste

Créer un projet contenant une API Flask avec un seul point d’entrée (/ping) qui retourne un message simple au format JSON.

Une solution

Étape 2 — Écrire un Dockerfile pour conteneuriser l’API

Créer un Dockerfile qui utilise une image Python légère et expose le port 5000.

Une solution

Étape 3 — Tester l’image Docker localement

Construire l’image Docker et lancer le conteneur pour vérifier que l’API fonctionne.

Une solution

Étape 4 — Initialiser un dépôt Git et pousser le projet sur GitHub

Créer un dépôt GitHub et y pousser le code source du projet.

Une solution

Étape 5 — Créer un fichier .github/workflows/docker.yml

Créer un fichier de workflow GitHub Actions pour construire l’image Docker à chaque push sur main et la publier sur Docker Hub.

Une solution

Étape 6 — Ajouter les secrets dans GitHub

Ajouter les identifiants Docker Hub dans les paramètres du dépôt GitHub.

Une solution

Étape 7 — Vérifier l’exécution du pipeline

Effectuer un git push pour déclencher le pipeline et vérifier que l’image Docker est publiée sur Docker Hub.

Une solution

Étape 8 — Lancer l’image depuis Docker Hub

Tester l’image publiée en la téléchargeant depuis Docker Hub et en la lançant localement.

Une solution

Étape 9 — Ajouter un tag de version à l’image Docker

Modifier le workflow pour ajouter un tag versionné basé sur le numéro de commit court ou une version définie.

Une solution

Étape 10 — Ajouter un test automatique dans le pipeline

Ajouter une étape dans le workflow pour vérifier que le port 5000 est bien exposé après le build.

Une solution