ITSkillsCenter
Développement Web

API design : créer des interfaces durables

9 دقائق للقراءة
API design : créer des interfaces durables

Ce que vous saurez faire à la fin

  1. Installer Docker Engine et Docker Compose sur Linux et Mac, puis vérifier que tout fonctionne avec un conteneur de test.
  2. Écrire un Dockerfile multi-stage pour une application web PHP ou Node.js, en réduisant l’image finale de 1,2 Go à 80 Mo.
  3. Orchestrer plusieurs services (app, base de données, cache Redis, reverse proxy Nginx) avec docker-compose et des volumes persistants.
  4. Pousser et tirer vos images depuis Docker Hub avec authentification, et automatiser le build pour vos équipes à Dakar ou Abidjan.
  5. Diagnostiquer les problèmes courants : conteneur qui crashe, port déjà utilisé, données perdues au redémarrage, image trop lourde.

Durée : 4h. Pré-requis : Linux/Mac (Ubuntu 22.04 ou macOS 13+), Git installé, compte Docker Hub gratuit, 4 Go de RAM libre, 10 Go d’espace disque, budget 0 FCFA pour la pratique locale.

Étape 1 — Comprendre pourquoi Docker change tout pour une PME

Avant Docker, déployer une application PHP sur un nouveau serveur prenait souvent 3 à 6 heures : installer la bonne version de PHP, les extensions, configurer Nginx, créer la base MySQL. Avec Docker, le même déploiement prend 8 minutes. Pour une PME sénégalaise qui gère 4 sites e-commerce et 2 applications internes, le gain dépasse 60 heures par mois. Docker emballe l’application avec toutes ses dépendances dans un conteneur isolé, qui tourne identiquement sur votre Mac à Dakar, sur le serveur de test à Abidjan et sur la production AWS à Paris.

Le coût d’un VPS pour héberger 5 conteneurs (Hetzner CX22, 4 Go RAM) descend à 4 000 FCFA par mois, contre 25 000 FCFA pour un hébergement mutualisé classique avec moins de flexibilité.

Étape 2 — Installer Docker sur Ubuntu 22.04

sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

sudo usermod -aG docker $USER
newgrp docker

docker run hello-world

La dernière commande télécharge une mini image et affiche un message de bienvenue. Si vous voyez « Hello from Docker! », l’installation est réussie. Sur Mac, téléchargez Docker Desktop depuis docker.com, installez le .dmg, ouvrez l’application et attendez la baleine verte dans la barre des tâches.

Étape 3 — Lancer un premier conteneur Nginx

docker run -d --name web-test -p 8080:80 nginx:alpine

docker ps

curl http://localhost:8080

docker logs web-test

docker stop web-test
docker rm web-test

Vous venez de lancer un serveur web Nginx accessible sur le port 8080 de votre machine, sans rien installer d’autre. L’image alpine pèse 23 Mo seulement. Pour un test rapide d’une démo client, c’est instantané.

Étape 4 — Écrire un Dockerfile pour une application Node.js

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:20-alpine AS runtime
WORKDIR /app
RUN addgroup -g 1001 -S nodejs && adduser -S nodeapp -u 1001
COPY --from=builder --chown=nodeapp:nodejs /app/dist ./dist
COPY --from=builder --chown=nodeapp:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodeapp:nodejs /app/package.json ./
USER nodeapp
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -q -O- http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]

Ce Dockerfile multi-stage compile l’application dans un premier conteneur (avec toutes les dépendances de build), puis copie uniquement les artefacts nécessaires dans une image finale légère. Résultat : 80 Mo au lieu de 1,2 Go. L’utilisateur non-root améliore la sécurité, indispensable si vous hébergez des données clients sénégalais soumises à la loi sur la protection des données personnelles.

Étape 5 — Construire et tester l’image

docker build -t mon-app:1.0 .

docker images | grep mon-app

docker run -d --name app-prod -p 3000:3000 mon-app:1.0

docker exec -it app-prod sh

docker stats app-prod --no-stream

La commande docker stats affiche la consommation CPU et RAM en temps réel. Une app Node.js bien optimisée tourne autour de 50 Mo de RAM au repos, contre 200 Mo pour une stack non containerisée équivalente.

Étape 6 — Dockerfile pour une application PHP avec Nginx

FROM composer:2.7 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts

FROM php:8.3-fpm-alpine AS app
RUN apk add --no-cache nginx supervisor && \
    docker-php-ext-install pdo_mysql opcache
COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/supervisord.conf /etc/supervisord.conf
COPY docker/php.ini /usr/local/etc/php/conf.d/custom.ini
WORKDIR /var/www/html
COPY --from=vendor /app/vendor ./vendor
COPY . .
RUN chown -R www-data:www-data /var/www/html
EXPOSE 80
CMD ["supervisord", "-c", "/etc/supervisord.conf"]

Cette image combine PHP-FPM et Nginx dans un seul conteneur via supervisord. Pour une boutique e-commerce WooCommerce ou un site Laravel, c’est la configuration standard. La taille finale tourne autour de 180 Mo, parfaite pour un déploiement rapide depuis un VPS à Dakar avec une connexion fibre limitée.

Étape 7 — Orchestrer plusieurs services avec docker-compose

version: "3.9"

services:
  web:
    build: .
    container_name: pme_web
    ports:
      - "8080:80"
    depends_on:
      db:
        condition: service_healthy
    environment:
      DB_HOST: db
      DB_USER: pme_user
      DB_PASSWORD: ChangeMe2026!
      DB_NAME: pme_prod
    volumes:
      - ./uploads:/var/www/html/uploads
    networks:
      - backend
    restart: unless-stopped

  db:
    image: mariadb:11
    container_name: pme_db
    environment:
      MARIADB_ROOT_PASSWORD: RootStrong2026!
      MARIADB_DATABASE: pme_prod
      MARIADB_USER: pme_user
      MARIADB_PASSWORD: ChangeMe2026!
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect"]
      interval: 10s
      retries: 5
    networks:
      - backend
    restart: unless-stopped

  cache:
    image: redis:7-alpine
    container_name: pme_cache
    networks:
      - backend
    restart: unless-stopped

volumes:
  db_data:

networks:
  backend:
    driver: bridge

Lancez tout avec docker compose up -d. Trois conteneurs démarrent en parallèle, communiquent sur un réseau privé bridge nommé « backend », et la base MariaDB persiste ses données dans le volume db_data même si le conteneur est supprimé.

Étape 8 — Comprendre volumes et réseaux

Les volumes Docker stockent les données hors du cycle de vie du conteneur. Sans volume, supprimer le conteneur MariaDB efface toutes les commandes de votre site e-commerce. Avec un volume nommé (db_data), vous pouvez détruire et recréer le conteneur sans perdre une ligne. Pour des sauvegardes, montez un volume bind qui pointe vers un dossier de votre disque hôte.

Les réseaux Docker isolent les conteneurs. Sur le réseau « backend », web peut joindre db simplement avec le nom « db » comme hôte, sans exposer le port MySQL au monde extérieur. Seul le port 8080 du service web est public. C’est la règle d’or : exposez le minimum.

Étape 9 — Tableau récapitulatif des commandes essentielles

Commande Usage Fréquence
docker ps -a Lister tous les conteneurs (actifs et stoppés) Quotidien
docker logs -f <nom> Suivre les logs en temps réel Quotidien
docker exec -it <nom> sh Ouvrir un shell dans un conteneur Hebdomadaire
docker compose up -d Lancer la stack en arrière-plan À chaque déploiement
docker compose down Arrêter et supprimer les conteneurs Maintenance
docker system prune -a Nettoyer images et conteneurs inutilisés Mensuel
docker volume ls Lister les volumes Avant sauvegarde
docker network inspect <net> Détailler un réseau Debug

Étape 10 — Pousser une image sur Docker Hub

docker login -u votre_utilisateur

docker tag mon-app:1.0 votre_utilisateur/mon-app:1.0
docker tag mon-app:1.0 votre_utilisateur/mon-app:latest

docker push votre_utilisateur/mon-app:1.0
docker push votre_utilisateur/mon-app:latest

docker pull votre_utilisateur/mon-app:1.0

Docker Hub est gratuit pour les dépôts publics. Pour un dépôt privé (recommandé pour vos clients), comptez 5 USD par mois soit 3 000 FCFA. Alternative : Gitea avec registre intégré sur votre VPS, gratuit après installation.

Étape 11 — Sauvegarder un volume pour un client

docker run --rm \
  -v pme_db_data:/data \
  -v $(pwd)/backups:/backup \
  alpine tar czf /backup/db_$(date +%Y%m%d).tar.gz -C /data .

ls -lh backups/

docker run --rm \
  -v pme_db_data:/data \
  -v $(pwd)/backups:/backup \
  alpine tar xzf /backup/db_20260423.tar.gz -C /data

Cette technique fonctionne pour tout volume : MySQL, MongoDB, fichiers uploadés, configurations Nginx. Automatisez via cron pour une sauvegarde nocturne envoyée vers Backblaze B2 (1 200 FCFA par mois pour 200 Go).

Étape 12 — Limiter les ressources d’un conteneur

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

Sans limites, un conteneur qui fuit peut consommer toute la RAM du serveur et planter les autres services. Sur un VPS partagé entre plusieurs clients PME, ces garde-fous sont obligatoires.

Étape 13 — Scanner une image pour les vulnérabilités

docker scout cves mon-app:1.0

docker scout recommendations mon-app:1.0

docker scout compare mon-app:1.0 --to mon-app:0.9

Docker Scout (intégré depuis 2023) audite votre image et signale les CVE critiques. Pour une boutique en ligne traitant des paiements Wave ou Orange Money, c’est un contrôle obligatoire avant chaque mise en production.

Erreurs classiques à éviter

  • Utiliser :latest en production : vous ne savez pas quelle version tourne, le rollback devient impossible. Toujours taguer avec un numéro précis (1.2.3).
  • Oublier les volumes : redémarrer la stack efface les données client. Catastrophe garantie le jour où votre site e-commerce perd 3 mois de commandes.
  • Exposer la base MySQL sur 0.0.0.0 : attaque par force brute en moins de 24 heures. Limitez aux réseaux internes Docker uniquement.
  • Mettre les mots de passe dans le Dockerfile : ils restent dans toutes les couches de l’image, lisibles par n’importe qui ayant accès au registre. Utilisez des variables d’environnement ou Docker secrets.
  • Construire l’image en root : si un attaquant exploite une faille, il prend le contrôle total. Toujours créer un utilisateur non-root.
  • Ne jamais nettoyer : en 6 mois, docker system df affiche 80 Go d’images obsolètes. Lancez docker system prune mensuellement.

Checklist Docker pour mise en production

✓ Image construite en multi-stage avec base alpine ou slim
✓ Utilisateur non-root configuré dans le Dockerfile
✓ Tag versionné (1.2.3) au lieu de :latest
✓ Healthcheck défini pour chaque service
✓ Volumes nommés pour toutes les données persistantes
✓ Réseau bridge dédié, pas de mode host
✓ Limites CPU et mémoire fixées dans docker-compose
✓ Logs rotatés (max-size 10m, max-file 3)
✓ Variables sensibles passées via .env, jamais en dur
✓ Image scannée avec docker scout cves
✓ Sauvegarde automatique des volumes critiques
✓ restart: unless-stopped sur les services critiques
✓ Documentation README avec docker compose up commands
✓ Test de restauration d'une sauvegarde validé
✓ Monitoring CPU/RAM activé (Portainer ou cAdvisor)
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité