30/01/2026

Docker dans le cycle de développement logiciel

Docker comme outil pour les développeurs : cohérence des environnements

Dans le monde du développement logiciel, l'un des défis majeurs est la gestion des environnements. Les différences entre les configurations des machines des développeurs, les serveurs de test et les environnements de production peuvent provoquer des dysfonctionnements imprévus. Docker, grâce à sa technologie de conteneurisation, offre une solution élégante pour garantir la cohérence des environnements à chaque étape du cycle de vie du développement logiciel.

La problématique des environnements incohérents

Les environnements de développement, de test et de production sont souvent hétérogènes. Cela peut résulter de différences dans les versions des bibliothèques, des dépendances ou même des systèmes d'exploitation. Ces écarts peuvent entraîner des bogues difficiles à reproduire, des pertes de temps lors de la phase de débogage et des retards dans les cycles de livraison.

Prenons un exemple concret : un développeur travaille sur une application Python sur sa machine locale avec une version spécifique de Python (par exemple, 3.9). En revanche, le serveur de test utilise une version plus ancienne (par exemple, 3.6), ce qui provoque des incompatibilités dans certaines fonctionnalités. Résultat : l'application fonctionne parfaitement en local, mais échoue en test ou en production. Docker élimine ce type de problème en encapsulant l'application et ses dépendances dans un conteneur isolé, garantissant que l'environnement reste identique où qu'il soit exécuté.

Docker et la portabilité des environnements

Ainsi que nous l'avons déjà abordé, Docker repose sur la création d'images, qui sont des modèles immuables contenant tout ce qui est nécessaire pour exécuter une application : le code source, les dépendances, les bibliothèques, les fichiers de configuration, et même le système d'exploitation si nécessaire. À partir de ces images, les développeurs peuvent lancer des conteneurs, qui sont des instances en cours d'exécution de ces images. Cette approche garantit que l'application s'exécute exactement de la même manière, que ce soit sur la machine d'un développeur, sur un serveur de test ou en production.

Prenons un autre exemple : imaginons une équipe qui développe une application web basée sur Node.js. Chaque développeur peut exécuter la commande suivante pour lancer l'application dans un environnement Docker, identique à celui utilisé par ses collègues ou les serveurs de production :

docker run -it -p 3000:3000 node:14

Cette commande crée un conteneur avec l'image officielle de Node.js version 14, sans que le développeur ait besoin d’installer Node.js directement sur sa machine. Peu importe que la machine soit sous Windows, macOS ou Linux : le conteneur s’exécutera de manière identique partout.

Cohérence des environnements dans le cycle de développement

Docker joue un rôle clé à chaque étape du cycle de développement logiciel :

  • Développement local : les développeurs peuvent utiliser des fichiers docker-compose.yml pour orchestrer facilement plusieurs services. Par exemple, une application web avec une base de données PostgreSQL peut être configurée ainsi :
version: '3.8'
services:
  web:
    image: python:3.9
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    command: python manage.py runserver
  db:
    image: postgres:13

Avec cette configuration, chaque membre de l'équipe travaille dans le même environnement, réduisant les risques d’incohérences.

  • Tests automatisés : Docker permet de créer des environnements éphémères pour exécuter des suites de tests. Par exemple, un pipeline CI/CD peut automatiquement lancer des conteneurs pour tester une application avec différentes configurations, puis les supprimer une fois les tests terminés.
  • Production : les conteneurs Docker peuvent être déployés directement sur des serveurs ou des orchestrateurs tels que Kubernetes. Cela garantit que ce qui a été testé et validé est identique à ce qui est déployé en production.

Réduction des conflits entre développeurs

Dans une équipe, il est courant que différents développeurs aient des configurations logicielles différentes. Docker résout ce problème en isolant les environnements de développement. Par exemple, si un développeur travaille sur une fonctionnalité nécessitant une ancienne version de PHP (par exemple, 7.4), et qu’un autre utilise une version plus récente (par exemple, 8.1), ils peuvent chacun exécuter leurs conteneurs sans interférer les uns avec les autres. Cela simplifie la collaboration et réduit les conflits liés aux environnements.

Standardisation des environnements grâce à Docker Hub

Docker Hub joue un rôle crucial dans la standardisation des environnements. Les développeurs peuvent utiliser des images officielles, maintenues par la communauté ou par les éditeurs de logiciels, comme base pour leurs projets. Par exemple, les images officielles de MySQL, Redis ou Python garantissent que l’application utilise un environnement fiable et cohérent.

De plus, les équipes peuvent créer leurs propres images personnalisées et les stocker sur des registries privés pour partager des environnements spécifiques à leurs projets. Cela renforce encore la cohérence et la portabilité entre les développeurs et les serveurs.

Exemple concret : gestion d'un projet complexe

Imaginons une équipe qui développe une application de commerce en ligne. L'application nécessite les éléments suivants :

  • Un serveur web basé sur Python.
  • Une base de données MySQL.
  • Un serveur de cache Redis.

Grâce à Docker, l'équipe peut configurer un fichier docker-compose.yml comme suit :

version: '3.8'
services:
  web:
    image: python:3.9
    ports:
      - "5000:5000"
    volumes:
      - ./app:/app
    command: python /app/app.py
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: example
  cache:
    image: redis:latest

Avec cette configuration, chaque membre de l'équipe peut lancer tous les services nécessaires en exécutant une seule commande :

docker compose up

Tous les développeurs utilisent ainsi un environnement identique, sans avoir à installer chaque composant individuellement sur leurs machines.

Intégration de Docker dans les workflows de développement (local et CI/CD)

Docker a transformé la manière dont les développeurs conçoivent, testent et déploient des applications. En s'intégrant parfaitement dans les workflows de développement, Docker permet d'uniformiser les environnements et d'automatiser les processus, que ce soit pour le travail local ou dans des pipelines d'intégration et de déploiement continus (CI/CD).

Docker dans le développement local

L'intégration de Docker dans le développement local repose sur la capacité de Docker à isoler les environnements et à simplifier la gestion des dépendances. Au lieu de configurer chaque machine avec des outils, bibliothèques ou bases de données spécifiques, Docker permet aux développeurs de tout encapsuler dans des conteneurs.

Exemple : développement d'une application Node.js

Un développeur travaillant sur une application Node.js peut utiliser Docker pour s'assurer que l'environnement est identique à celui de ses coéquipiers. Voici un exemple d'utilisation :

Commençons par créer un fichier Dockerfile :

FROM node:14
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
EXPOSE 3000

Lançons un conteneur pour l'application avec les deux commandes suivantes :

docker build -t mon-app . 
docker run -p 3000:3000 -v $(pwd):/app -d mon-app

Avec cette approche, tout développeur peut cloner le projet, exécuter la commande Docker et obtenir un environnement fonctionnel, sans avoir à installer Node.js ou les dépendances localement.

Docker dans les pipelines CI/CD

Dans les workflows modernes, l'intégration continue (CI) et le déploiement continu (CD) sont essentiels pour assurer la qualité et la rapidité des livraisons. Docker s'intègre parfaitement dans ces processus en permettant d’automatiser les tests, la construction des images, et le déploiement.

Exemple : pipeline CI avec GitHub Actions

Voyons ensemble comment Docker peut être intégré dans un pipeline CI pour une application Python.

Commençons par créer un fichier Dockerfile :

FROM python:3.9
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]

Nous procédons à la configuration de GitHub Actions (.github/workflows/ci.yml) :

name: CI Pipeline

on:
  push:
    branches:
      - main

jobs:
  build-and-test:
    runs-on: ubuntu-latest

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

    - name: Build Docker image
      run: docker build -t mon-app .

    - name: Run tests
      run: docker run mon-app pytest

Que fait ce pipeline ?

Il effectue les étapes suivantes :

  • Récupère le code source.
  • Construit une image Docker.
  • Exécute les tests unitaires dans un conteneur.

Déploiement continu avec Docker

Une fois les tests validés, Docker facilite également le déploiement :

Nous publions l'image sur une registry, par exemple Docker Hub :

docker tag mon-app mon-organisation/mon-app:v1.0 
docker push mon-organisation/mon-app:v1.0

Il nous reste ensuite à déployer l'image sur un orchestrateur comme Kubernetes ou directement sur un serveur, ce que nous aurons l'occasion de pratiquer ultérieurement.

TP : intégration de Docker dans un workflow CI/CD avec Apache et PHP

Nous allons pratiquer ensemble un TP afin de concrétiser nos explications exposées tout au long de ce cours.

Objectif : mettre en place un environnement conteneurisé pour une application PHP utilisant Apache, puis configurer un pipeline CI/CD pour automatiser les tests et le déploiement.

Étape 1 : préparation de l'application PHP

Créez un dossier nommé workflow-apache-php contenant index.php :

<?php
echo "Bonjour, je suis une super application PHP pour le TP de workflow avec Apache et PHP !";
?>

Étape 2 : création du Dockerfile

Le Dockerfile définira l'environnement Apache et PHP.

# Utiliser une image de base Apache avec PHP préinstallé
FROM php:8.2-apache

# Copier les fichiers de l'application dans le dossier racine web d'Apache
COPY . /var/www/html/

# Donner les permissions nécessaires
RUN chown -R www-data:www-data /var/www/html

# Exposer le port 80 pour le serveur Apache
EXPOSE 80

Étape 3 : test local de l'application avec Docker

Construisons l'image Docker :

docker build -t workflow-apache-php .

Lançons le conteneur :

docker run -d -p 8080:80 workflow-apache-php

Une fois le conteneur lancé, vérifions. Pour ce faire, faisons curl -f http://localhost:8080 | grep "Bonjour". Nous devrions voir le message dans la console :

Bonjour, je suis une super application PHP pour le TP de workflow avec Apache et PHP !

Étape 4 : Automatisation avec Docker Compose

Ajoutons un fichier docker-compose.yml pour orchestrer facilement le lancement de tous les services. Nous reviendrons plus tard, dans un prochain chapitre, sur les explications détaillées sur Docker Compose.

version: '3.8'
services:
  web:
    build: .
    ports:
      - "8080:80"
    volumes:
      - .:/var/www/html

Nous lançons tous les services (en mode détaché) :

docker compose up -d

Étape 5 : Configuration d'un pipeline CI avec GitHub Actions

Au préalable, nous devons nous connecter sur GitHub. Vous devez créer un compte si vous n'en avez pas.
Vous devez créer un nouveau dépôt (repository). Une fois dans votre nouveau dépôt, cliquez sur l’onglet Actions dans la barre de navigation.

GitHub nous propose des modèles pré-configurés pour les workflows. Cliquez sur Configure pour en utiliser un ou choisissez New workflow pour créer le vôtre.
Nous choisissons de créer un workflow personnalisé avec Set up a workflow yourself.


Un éditeur en ligne s'ouvrira avec un fichier prérempli nommé main.yml. Modifions son contenu pour inclure notre propre workflow :

La structure du pipeline est composée de telle sorte à ce qu'il puisse :

  • Récupérer le code.
  • Construire l'image Docker.
  • Lancer un conteneur pour tester l'application.

Créons un fichier GitHub Actions (.github/workflows/ci.yml) :

name: CI Apache PHP

on:
  push:
    branches:
      - main

jobs:
  build-and-test:
    runs-on: ubuntu-latest

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

    - name: set up Docker
      uses: docker/setup-buildx-action@v2

    - name: build Docker image
      run: docker build -t workflow-apache-php .

    - name: run container and test application
      run: |
        docker run -d -p 8080:80 workflow-apache-php
        sleep 5
        curl -f http://localhost:8080

Étape 6 : Déploiement continu

Ajoutez une étape pour pousser l'image sur Docker Hub après validation des tests.

Configurons les secrets GitHub : nous devons ajouter les secrets DOCKER_USERNAME et DOCKER_PASSWORD dans les paramètres de votre dépôt GitHub.

Puis nous mettons à jour le fichier CI pour inclure le déploiement :

    - name: push Docker image
      run: |
        echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
        docker tag workflow-apache-php:latest my-dockerhub-account/workflow-apache-php:latest
        docker push my-dockerhub-account/workflow-apache-php:latest

Voici notre fichier GitHub Actions finalisé :

name: CI/CD Pipeline for Docker

on:
  push:
    branches:
      - main

jobs:
  build-test-push:
    runs-on: ubuntu-latest

    steps:
    # Étape 1 : récupérer le code source
    - name: checkout code
      uses: actions/checkout@v3

    # Étape 2 : construire l'image Docker
    - name: build Docker image
      run: docker build -t workflow-apache-php .

    # Étape 3 : tester l'application
    - name: run container and test application
      run: |
        docker run -d -p 8080:80 --name test-container workflow-apache-php
        sleep 10
        curl -f http://localhost:8080
        docker stop test-container
        docker rm test-container

    # Étape 4 : pousser l'image sur Docker Hub
    - name: push Docker image
      env:
        DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
        DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
      run: |
        echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
        docker tag workflow-apache-php:latest $DOCKER_USERNAME/workflow-apache-php:latest
        docker push $DOCKER_USERNAME/workflow-apache-php:latest

Pour rappel, $DOCKER_USERNAME et $DOCKER_PASSWORD sont nos secrets contenant nos identifiants Docker Hub. Ils sont définis dans les paramètres de sécurité de GitHub Actions.

Enregistrons le fichier main.yml avec le bouton Commit changes (situé sur la droite).

À présent, poussons nos fichiers sur le repository Git. Nous supposons avoir déjà initialisé le repo local avec git init.

Notre action se déclenche comme prévu.

Après un petit temps d'attente, nous constatons que celui-ci a été correctement terminé.

Notre image a été automatiquement correctement poussée sur le registry Docker Hub et s'affiche dans la liste de notre repository personnel :

Quels sont les composants que nous avons mis en place ?

  • Une application PHP fonctionnelle servie par Apache, testée et conteneurisée.
  • Un pipeline CI qui construit, teste et déploie l'application.
  • Une image Docker publiée sur Docker Hub, prête à être déployée.

Bonus (facultatif) : déploiement sur un serveur

Pour aller plus loin, déployez l'application sur un serveur ou un cluster Kubernetes en utilisant l'image Docker générée. Vous pouvez par exemple utiliser un fichier kubectl pour automatiser ce déploiement.

Dans les prochains chapitres de ce cours, ces notions seront abordées plus en détail et nous évoquerons aussi l'utilisation de Kubernetes.

author avatar
Jérémy GAK
Jérémy GAK est un ingénieur Linux doté de plus de 11 ans d'expérience dans le domaine. Sa carrière diversifiée s'étend de l'administration système et réseau à une expertise pointue en sécurité informatique. Consultant et ingénieur système de métier et actif dans la veille technologique, il est expert sur les technologies open source, l'automatisation des processus et la cybersécurité.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.