CI/CD avec Docker
Automatiser le déploiement d'applications avec des conteneurs
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.
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
- Créer un projet contenant un fichier
app.py
:
print("Application CI/CD avec Docker")
- Créer un
Dockerfile
:
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
CMD ["python", "app.py"]
- 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
-
Ajouter les secrets
DOCKER_USERNAME
etDOCKER_PASSWORD
dans les paramètres du dépôt GitHub -
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
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
Vous devez être connecté pour voir le contenu.
É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
Vous devez être connecté pour voir le contenu.
Étape 3 — Tester l’image Docker localement
Construire l’image Docker et lancer le conteneur pour vérifier que l’API fonctionne.
Une solution
Vous devez être connecté pour voir le contenu.
É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
Vous devez être connecté pour voir le contenu.
É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
Vous devez être connecté pour voir le contenu.
Étape 6 — Ajouter les secrets dans GitHub
Ajouter les identifiants Docker Hub dans les paramètres du dépôt GitHub.
Une solution
Vous devez être connecté pour voir le contenu.
É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
Vous devez être connecté pour voir le contenu.
É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
Vous devez être connecté pour voir le contenu.
É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
Vous devez être connecté pour voir le contenu.
É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
Vous devez être connecté pour voir le contenu.