Docker pour Développeurs : Maîtriser la Conteneurisation en 2025

Un guide pratique complet pour apprendre Docker, conteneuriser ses applications et créer des environnements de développement reproductibles.

Docker pour Développeurs : Maîtriser la Conteneurisation en 2025

Introduction

"Ça marche sur ma machine" est une phrase que tout développeur a prononcée au moins une fois. Docker a été créé pour résoudre exactement ce problème. En 2025, la conteneurisation est devenue un standard incontournable dans l'industrie du développement logiciel.

Que vous soyez développeur web, backend ou full-stack, comprendre Docker est désormais essentiel. Ce guide vous emmène du niveau débutant à l'utilisation pratique de Docker dans vos projets quotidiens.

Qu'est-ce que Docker ?

Docker est une plateforme qui permet d'empaqueter, distribuer et exécuter des applications dans des conteneurs isolés. Un conteneur inclut tout ce dont votre application a besoin : code, runtime, bibliothèques système et dépendances.

Conteneurs vs Machines Virtuelles

┌─────────────────────────────────┐  ┌─────────────────────────────────┐
│     Machine Virtuelle           │  │         Conteneur               │
├─────────────────────────────────┤  ├─────────────────────────────────┤
│  App A  │  App B  │  App C      │  │  App A  │  App B  │  App C      │
│  Bins   │  Bins   │  Bins       │  │  Bins   │  Bins   │  Bins       │
│  Libs   │  Libs   │  Libs       │  │  Libs   │  Libs   │  Libs       │
├─────────┼─────────┼─────────────┤  ├─────────┴─────────┴─────────────┤
│ Guest OS│ Guest OS│ Guest OS    │  │      Docker Engine              │
├─────────┴─────────┴─────────────┤  ├─────────────────────────────────┤
│       Hyperviseur               │  │       Système d'exploitation    │
├─────────────────────────────────┤  └─────────────────────────────────┘
│   Système d'exploitation        │
└─────────────────────────────────┘

  Lourd, Lent, GB de RAM              Léger, Rapide, MB de RAM

Avantages des conteneurs :

  • Démarrage en quelques secondes (vs minutes pour les VMs)
  • Utilisation minimale des ressources
  • Portabilité totale
  • Isolation des processus
  • Scalabilité horizontale facile

Installation et premiers pas

Installation de Docker

Linux (Ubuntu/Debian) :

# Mise à jour des paquets
sudo apt update

# Installation des dépendances
sudo apt install apt-transport-https ca-certificates curl software-properties-common

# Ajout de la clé GPG Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Ajout du dépôt Docker
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

# Installation de Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

# Ajouter votre utilisateur au groupe docker
sudo usermod -aG docker $USER

macOS / Windows :
Téléchargez Docker Desktop depuis docker.com

Vérification de l'installation

docker --version
# Docker version 24.0.7, build afdd53b

docker run hello-world
# Hello from Docker! 🎉

Concepts fondamentaux

1. Images Docker

Une image est un modèle immuable contenant votre application et ses dépendances. C'est comme un "snapshot" de votre environnement.

# Télécharger une image depuis Docker Hub
docker pull nginx:latest

# Lister les images locales
docker images

# Rechercher des images
docker search python

2. Conteneurs

Un conteneur est une instance en cours d'exécution d'une image.

# Démarrer un conteneur
docker run -d -p 8080:80 --name mon-nginx nginx:latest

# Lister les conteneurs en cours
docker ps

# Lister tous les conteneurs (même arrêtés)
docker ps -a

# Arrêter un conteneur
docker stop mon-nginx

# Démarrer un conteneur arrêté
docker start mon-nginx

# Supprimer un conteneur
docker rm mon-nginx

Options importantes :

  • -d : mode détaché (arrière-plan)
  • -p 8080:80 : mapping de ports (hôte:conteneur)
  • --name : nom du conteneur
  • -v : montage de volumes
  • -e : variables d'environnement

3. Volumes

Les volumes permettent de persister les données au-delà du cycle de vie d'un conteneur.

# Créer un volume
docker volume create mes-donnees

# Utiliser un volume
docker run -d -v mes-donnees:/data --name mon-app mon-image

# Lister les volumes
docker volume ls

# Inspecter un volume
docker volume inspect mes-donnees

Créer votre premier Dockerfile

Un Dockerfile est un fichier texte contenant les instructions pour construire une image.

Exemple : Application Node.js

# Utiliser une image de base officielle
FROM node:18-alpine

# Définir le répertoire de travail
WORKDIR /app

# Copier les fichiers de dépendances
COPY package*.json ./

# Installer les dépendances
RUN npm ci --only=production

# Copier le code source
COPY . .

# Exposer le port de l'application
EXPOSE 3000

# Définir la commande de démarrage
CMD ["node", "server.js"]

Instructions Dockerfile courantes :

  • FROM : image de base
  • WORKDIR : définit le répertoire de travail
  • COPY : copie des fichiers de l'hôte vers l'image
  • RUN : exécute une commande lors du build
  • EXPOSE : documente le port utilisé
  • CMD : commande par défaut au démarrage
  • ENV : définit des variables d'environnement
  • ENTRYPOINT : point d'entrée de l'application

Construire et exécuter l'image

# Construire l'image
docker build -t mon-app:1.0 .

# Exécuter le conteneur
docker run -d -p 3000:3000 --name mon-app-container mon-app:1.0

# Voir les logs
docker logs mon-app-container

# Voir les logs en temps réel
docker logs -f mon-app-container

Exemple pratique : Stack LAMP/LEMP

Application PHP avec MySQL et Nginx

Structure du projet :

mon-projet/
├── docker-compose.yml
├── nginx/
│   └── default.conf
├── php/
│   └── Dockerfile
└── src/
    └── index.php

docker-compose.yml :

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
    networks:
      - app-network

  php:
    build:
      context: ./php
      dockerfile: Dockerfile
    volumes:
      - ./src:/var/www/html
    networks:
      - app-network
    environment:
      - DB_HOST=mysql
      - DB_NAME=mabase
      - DB_USER=user
      - DB_PASSWORD=secret

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootsecret
      MYSQL_DATABASE: mabase
      MYSQL_USER: user
      MYSQL_PASSWORD: secret
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app-network
    ports:
      - "3306:3306"

  phpmyadmin:
    image: phpmyadmin:latest
    ports:
      - "8081:80"
    environment:
      PMA_HOST: mysql
      PMA_USER: user
      PMA_PASSWORD: secret
    depends_on:
      - mysql
    networks:
      - app-network

volumes:
  mysql-data:

networks:
  app-network:
    driver: bridge

php/Dockerfile :

FROM php:8.3-fpm-alpine

# Installer les extensions PHP nécessaires
RUN docker-php-ext-install pdo pdo_mysql mysqli

# Installer Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

nginx/default.conf :

server {
    listen 80;
    server_name localhost;
    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

src/index.php :

<?php
$host = getenv('DB_HOST');
$db = getenv('DB_NAME');
$user = getenv('DB_USER');
$pass = getenv('DB_PASSWORD');

try {
    $pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
    echo "<h1>Connexion à MySQL réussie ! 🎉</h1>";
    echo "<p>Version PHP : " . phpversion() . "</p>";
} catch (PDOException $e) {
    echo "Erreur : " . $e->getMessage();
}
?>

Démarrer la stack complète

# Démarrer tous les services
docker-compose up -d

# Voir les logs de tous les services
docker-compose logs -f

# Voir les logs d'un service spécifique
docker-compose logs -f nginx

# Arrêter tous les services
docker-compose down

# Arrêter et supprimer les volumes
docker-compose down -v

Accédez à votre application :

Docker Compose : Orchestration simplifiée

Docker Compose permet de définir et gérer des applications multi-conteneurs.

Commandes essentielles

# Démarrer les services
docker-compose up -d

# Reconstruire les images
docker-compose build

# Démarrer et reconstruire si nécessaire
docker-compose up -d --build

# Arrêter les services
docker-compose stop

# Arrêter et supprimer les conteneurs
docker-compose down

# Voir l'état des services
docker-compose ps

# Exécuter une commande dans un service
docker-compose exec php php -v

# Voir les logs
docker-compose logs -f service-name

Bonnes pratiques Docker

1. Optimisation des images

Utilisez des images légères :

# ❌ Mauvais : image lourde
FROM ubuntu:latest
RUN apt-get update && apt-get install -y nodejs npm

# ✅ Bon : image Alpine légère
FROM node:18-alpine

Multi-stage builds pour réduire la taille :

# Stage 1 : Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2 : Production
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]

2. Sécurité

# ✅ Ne pas exécuter en tant que root
FROM node:18-alpine
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs

# ✅ Copier seulement ce qui est nécessaire
COPY --chown=nodejs:nodejs . .

# ✅ Utiliser des versions spécifiques
FROM node:18.17.1-alpine3.18

3. Fichier .dockerignore

Créez un .dockerignore pour exclure les fichiers inutiles :

node_modules
npm-debug.log
.git
.env
*.md
.vscode
.idea
coverage
.DS_Store

4. Variables d'environnement

# docker-compose.yml
services:
  app:
    env_file:
      - .env
    environment:
      - NODE_ENV=production
      - PORT=3000
# .env
DB_HOST=mysql
DB_PORT=3306
DB_NAME=mydatabase
API_KEY=your_secret_key

Cas d'usage avancés

1. Développement local avec hot-reload

version: '3.8'

services:
  app:
    build: .
    volumes:
      - ./src:/app/src  # Synchronisation du code
      - /app/node_modules  # Éviter d'écraser node_modules
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    command: npm run dev  # Mode développement

2. Tests automatisés

services:
  test:
    build: .
    command: npm test
    environment:
      - NODE_ENV=test
      - DB_HOST=test-db
  
  test-db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: testdb
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
# Exécuter les tests
docker-compose run --rm test

3. CI/CD avec Docker

Exemple GitHub Actions :

name: CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Build Docker image
      run: docker build -t mon-app:${{ github.sha }} .
    
    - name: Run tests
      run: docker run mon-app:${{ github.sha }} npm test
    
    - name: Push to registry
      if: github.ref == 'refs/heads/main'
      run: |
        echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
        docker push mon-app:${{ github.sha }}

Débogage et maintenance

Inspection et débogage

# Inspecter un conteneur
docker inspect mon-conteneur

# Exécuter une commande dans un conteneur en cours
docker exec -it mon-conteneur bash

# Voir les ressources utilisées
docker stats

# Voir les processus dans un conteneur
docker top mon-conteneur

# Copier des fichiers depuis/vers un conteneur
docker cp mon-conteneur:/app/logs/error.log ./local-logs/
docker cp ./config.json mon-conteneur:/app/config/

Nettoyage

# Supprimer les conteneurs arrêtés
docker container prune

# Supprimer les images non utilisées
docker image prune -a

# Supprimer les volumes non utilisés
docker volume prune

# Nettoyage complet (attention !)
docker system prune -a --volumes

# Voir l'espace disque utilisé
docker system df

Docker en production

1. Orchestration avec Docker Swarm

# Initialiser Swarm
docker swarm init

# Déployer une stack
docker stack deploy -c docker-compose.yml mon-app

# Scaler un service
docker service scale mon-app_web=5

# Lister les services
docker service ls

2. Monitoring et logs

# docker-compose.yml avec monitoring
version: '3.8'

services:
  app:
    image: mon-app
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

3. Health checks

FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm ci --only=production

HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
  CMD node healthcheck.js || exit 1

CMD ["node", "server.js"]

Ressources et aller plus loin

Registres Docker populaires

  • Docker Hub : hub.docker.com (registre public officiel)
  • GitHub Container Registry : ghcr.io
  • GitLab Container Registry : registry.gitlab.com
  • AWS ECR, Google GCR, Azure ACR : registres cloud privés

Commandes pour gérer les registres

# Se connecter à un registre
docker login

# Tag une image pour un registre
docker tag mon-app:latest username/mon-app:latest

# Pousser vers un registre
docker push username/mon-app:latest

# Pull depuis un registre privé
docker pull registry.example.com/mon-app:latest

Alternatives et compléments

  • Podman : alternative sans daemon à Docker
  • Kubernetes : orchestration à grande échelle
  • Docker Desktop : GUI pour gérer Docker
  • Portainer : interface web pour gérer Docker
  • Traefik : reverse proxy et load balancer

Conclusion

Docker a révolutionné la façon dont nous développons et déployons des applications. En 2025, c'est une compétence incontournable pour tout développeur moderne.

Points clés à retenir :

✅ Docker garantit la cohérence entre développement et production
✅ Les conteneurs sont légers et rapides à démarrer
✅ Docker Compose simplifie la gestion d'applications multi-conteneurs
✅ Les bonnes pratiques améliorent sécurité et performance
✅ Docker s'intègre parfaitement dans les pipelines CI/CD

Prochaines étapes :

  1. Conteneurisez votre prochain projet
  2. Explorez Docker Compose pour des stacks complètes
  3. Apprenez Kubernetes pour l'orchestration à grande échelle
  4. Intégrez Docker dans votre pipeline CI/CD

Ressources utiles


Steven KOULO
Steven KOULODéveloppeur Fullstack

Besoin d'un développeur pour votre prochain projet ? Je suis disponible pour des missions freelance.

Me contacter