E-NO
DevOps 13 min de lecture

Planification de capacité Docker Compose avec exemples pratiques

calendar_today Publié : 2026-08-16
update Dernière mise à jour : 2026-08-16
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Planification de capacité Docker Compose avec exemples pratiques ».

La planification de capacité dans Docker Compose est la discipline pratique consistant à dimensionner correctement le CPU, la mémoire et les E/S pour chaque service afin que votre pile reste rapide, prévisible et récupérable à mesure que la charge augmente. Ce guide parcourt une boucle complète : inventorier votre environnement, appliquer des limites de ressources sûres dans le format de fichier Compose 2.4, vérifier que les limites sont appliquées, définir des signaux de mise à l'échelle, gérer les modes de défaillance courants et exécuter une liste de contrôle opérationnelle reproductible. Les exemples utilisent Nginx, PostgreSQL et Redis. Tous les nombres marqués comme exemples construits sont des points de départ seulement ; mesurez et affinez pour votre charge de travail.

---

Inventaire de l'environnement et des versions

Avant de modifier les limites, construisez un inventaire court. Vous devez savoir exactement ce que vous dimensionnez et quelles garde-fous l'hôte supporte.

Prérequis :

  • OS hôte : Linux, ou Docker Desktop avec un backend Linux
  • Docker Engine : 20.10+ (hôtes compatibles cgroups v2 recommandés)
  • Plugin Docker Compose : v2.20+ (invoqué comme docker compose)
  • Accès sudo pour les commandes système et Docker

Liste de contrôle d'inventaire :

  • Enregistrer les versions de Docker Engine et Compose : docker version, docker compose version
  • Capacité de l'hôte : nproc, free -h, lsblk -o NAME,SIZE,TYPE,MOUNTPOINT
  • Cgroups : mount | grep cgroup, confirmer que les contrôleurs memory et pids sont activés
  • Topologie Compose actuelle : services, réseaux, volumes
  • Métriques de référence : CPU au repos, empreinte mémoire, latence disque (ex. iostat -x 1 5)

Conservez cet inventaire dans votre dépôt ou votre runbook afin que les futures modifications référencent une base connue.

---

Chemin de configuration sûr

Pour Docker Compose autonome (non-Swarm), utilisez le format de fichier Compose 2.4 pour appliquer des limites par service directement. Évitez deploy.resources car il est destiné à l'ordonnancement Swarm et peut être ignoré dans Compose non-Swarm.

Options clés dans Compose v2.4 :

  • cpus : limite CPU fractionnaire par conteneur (ex. 0.50)
  • mem_limit : plafond mémoire dur (ex. 512m)
  • mem_reservation : réservation mémoire souple indicatrice (ex. 384m)
  • pids_limit : nombre maximal de processus par conteneur
  • ulimits : descripteurs de fichiers et autres limites par processus
  • shm_size : taille de la mémoire partagée (important pour PostgreSQL)
  • restart : politique de redémarrage du conteneur pour la résilience
  • healthcheck : vérifications de vivacité de base pour ordonner les dépendances et vérifier le démarrage

Conseils de sécurité :

  • Déployez les limites de manière incrémentale. Préférez commencer par des réservations et des plafonds doux.
  • Maintenez 20 à 30 % de marge pendant l'opération normale pour le CPU et la mémoire.
  • Changez une variable par itération ; vérifiez avant d'autres modifications.

---

Exemple construit : Nginx, PostgreSQL, Redis

Voici un docker-compose.yml construit utilisant le format de fichier Compose 2.4. Remplacez les versions d'images par celles que vous standardisez. Les nombres sont des points de départ ; ajustez avec des mesures.

version: "2.4"

services:
  web:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"
    depends_on:
      - cache
      - db
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost/ || exit 1"]
      interval: 10s
      timeout: 3s
      retries: 5
    cpus: "0.50"                 # point de départ exemple construit
    mem_limit: "256m"
    mem_reservation: "192m"
    pids_limit: 256
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    restart: unless-stopped
    networks: [appnet]

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
      interval: 10s
      timeout: 5s
      retries: 10
    cpus: "1.00"                 # point de départ exemple construit
    mem_limit: "2g"
    mem_reservation: "1g"
    shm_size: "512m"             # meilleur pour les plans de requête et les tris
    pids_limit: 4096
    ulimits:
      nofile:
        soft: 262144
        hard: 262144
    restart: unless-stopped
    networks: [appnet]

  cache:
    image: redis:7-alpine
    command: ["redis-server", "--save", "", "--appendonly", "no"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 10
    cpus: "0.50"                 # point de départ exemple construit
    mem_limit: "512m"
    mem_reservation: "384m"
    pids_limit: 1024
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    restart: unless-stopped
    networks: [appnet]

networks:
  appnet:
    driver: bridge

volumes:
  pgdata:

Pourquoi ces réglages (rationale construite) :

  • web est lié aux E/S et bénéficie d'une marge sur les descripteurs de fichiers. Un CPU et une RAM modestes suffisent à petite échelle.
  • db est sensible à la mémoire ; lui donner plus de RAM réduit les E/S en permettant des caches plus grands. shm_size réduit les débordements vers fichiers temporaires lors de gros tris et jointures de hachage.
  • cache est mono-thread mais sensible à la latence ; CPU 0.5 avec 384–512 Mo RAM fournit une plage de départ sûre.

Résumé des limites de départ construites (à modifier au fur et à mesure) :

ServiceCPU (cpus)Limite memRéservation memLimite PIDsNotes
web0.50256m192m256Augmenter nofile pour connexions concurrentes
db1.002g1g4096Plus de RAM réduit E/S disque ; ajouter shm_size
cache0.50512m384m1024Garder AOF désactivé pour caches sensibles à la latence

Source : exemple construit pour dimensionnement initial seulement

Monter la pile et confirmer :

# Valider le fichier
docker compose -f docker-compose.yml config

# Démarrer les services
docker compose -f docker-compose.yml up -d

# Lister les conteneurs et leur santé
docker compose ps

Résultat attendu :

  • Tous les services affichent Up avec (healthy) après le passage de leurs vérifications.
  • L'utilisation CPU et mémoire de l'hôte reste dans une marge sûre.

---

Vérification et diagnostics

1. Confirmer les limites appliquées

# Remplacer <id> par l'ID du conteneur de chaque service
cid_web=$(docker compose ps -q web)
cid_db=$(docker compose ps -q db)
cid_cache=$(docker compose ps -q cache)

# Vérifier les contraintes CPU et mémoire
for c in $cid_web $cid_db $cid_cache; do
  echo "Inspection $c";
  docker inspect $c --format='Nom: {{.Name}}
 NanoCPUs: {{.HostConfig.NanoCpus}}
 Memoire: {{.HostConfig.Memory}}
 PidsLimit: {{.HostConfig.PidsLimit}}
 ShmSize: {{.HostConfig.ShmSize}}
';
done

Résultat attendu :

  • NanoCpus correspond à votre cpus multiplié par 1e9 (ex. 0.5 → 500000000).
  • Memoire équivaut aux octets pour votre mem_limit (ex. 256m → 268435456).
  • PidsLimit et ShmSize (db) correspondent à votre configuration.

2. Observer l'utilisation en temps réel

docker stats --no-stream

Résultat attendu :

  • MEM USAGE / LIMIT reste confortablement sous LIMIT pendant l'activité typique.
  • CPU % flotte sous votre allocation CPU effective en régime permanent.

3. Valider la santé et la disponibilité

# État de santé
docker inspect $cid_web --format='{{json .State.Health}}' | jq .

# Vérification HTTP simple
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/

Résultat attendu :

  • L'état de santé rapporte healthy pour tous les services.
  • curl retourne 200 depuis web.

4. Diagnostics par les journaux

docker compose logs --since=10m --tail=200

Recherchez les messages OOM, throttling ou retry. Les signaux typiques incluent OOMKilled, réinitialisations de connexion ou blocages d'écriture.

5. Sonde de charge légère (construite)

Vous pouvez simuler une petite rafale pour vérifier que la marge existe :

# 50 requêtes rapides, sérialisées (exemple construit)
for i in $(seq 1 50); do curl -s -o /dev/null -w '.' http://localhost:8080/; done; echo

Résultat attendu :

  • Les réponses se terminent rapidement sans pics d'erreurs ou redémarrages de conteneurs.

---

Signaux et limites de mise à l'échelle

Définissez des signaux et seuils clairs qui déclenchent la mise à l'échelle ou le redimensionnement. Ce qui suit sont des nombres d'exemples construits que vous pouvez adopter pour des pilotes et affiner plus tard.

SignalFenêtre cible (construite)ActionComment vérifier
Utilisation CPU≤ 70% pendant 10+ minutesAjouter 0.5 CPU ou 1 réplica (sans état)docker stats, APM applicatif
Marge mémoire≥ 25% libre vs limiteAugmenter mem_limit de 25–50%docker stats, journaux OOM
Latence HTTP p99≤ 300 ms stableMettre à l'échelle réplicas web/app ; ajuster keepaliveMétriques app, journaux d'accès
Latence ops Redis≤ 2 ms p99Ajouter CPU ou réduire AOF/durabilitéRedis INFO, métriques app
Temps checkpoint DB≤ 1 minAugmenter RAM, ajuster WAL/checkpointJournaux Postgres, pg_stat_bgwriter
Profondeur fileVidée dans SLAMettre à l'échelle workers horizontalementMétriques app/file

Source : seuils initiaux construits ; calibrer avec vos SLO

Notes sur les actions :

  • Préférez la mise à l'échelle horizontale pour les niveaux sans état ; augmentez les limites par réplica seulement quand l'utilisation montre un throttling CPU ou une pression garbage-collection.
  • Pour PostgreSQL, de la RAM supplémentaire surpasse souvent les augmentations CPU jusqu'à ce que l'ensemble de travail tienne mieux en cache.
  • Maintenez une marge de sécurité : visez 20–30 % de capacité inutilisée en régime permanent.

Exemple de mise à l'échelle (worker construit) :

Si vous avez un service worker sans état sans ports liés à l'hôte, vous pouvez ajouter des réplicas en toute sécurité :

# Exemple construit : mettre à l'échelle un service worker
# Remplacer 'worker' par votre nom de service réel
docker compose up -d --scale worker=3

Résultat attendu :

  • Les nouveaux réplicas rejoignent le même réseau et consomment la même file/sujet.
  • Le CPU et la mémoire de l'hôte restent dans la marge. Sinon, revenez en arrière ou ajoutez de la capacité hôte.

---

Modes de défaillance et récupération

Problèmes courants que vous rencontrerez et comment récupérer en toute sécurité.

Mode de défaillanceSymptômeVérification rapideRécupération
OOM killConteneur redémarre, OOMKilled=truedocker inspect .State.OOMKilled, journauxAugmenter mem_limit, réduire heap/cache, ou diviser la charge ; redémarrer
Throttling CPULatence élevée, débit inégaldocker stats CPU % élevé, dmesg throttling CFSAugmenter cpus, mettre à l'échelle, ou réduire coût par requête
Saturation E/Siowait élevé, écritures DB lentesiostat -x, checkpoints Postgres lentsAugmenter RAM (cache), déplacer données vers disque plus rapide, ajuster WAL/checkpoint
Épuisement descripteursErreurs EMFILEJournaux app, ulimit -n dans conteneurAugmenter ulimits.nofile ; redémarrer
Limite PIDs atteinteÉchecs fork/execdocker inspect .HostConfig.PidsLimitAugmenter pids_limit ; revoir modèle de processus
Croissance journaux remplit disqueDisque 100% pleindf -h, taille journauxRotater/tronquer journaux, déplacer vers logging externe, plafonner rétention

Source : entrées runbook construites pour services conteneurisés courants

Étapes de retour arrière et récupération :

  1. Soulagement immédiat
  • Augmenter temporairement mem_limit ou cpus pour le service impacté, puis docker compose up -d pour appliquer.
  • Si l'hôte est épuisé, réduire d'abord les services non critiques ou déplacer la charge hors-hôte.
  1. Configuration connue-bonne
  • Revenir au dernier commit compose connu-bon :
     git checkout <commit_connu_bon> -- docker-compose.yml
     docker compose up -d
  1. Récupération base de données
  • Si PostgreSQL est en récupération après crash, laissez-lui le temps de rejouer le WAL. Si corruption suspectée, restaurer depuis votre dernière sauvegarde vérifiée vers le volume pgdata.
  1. Valider la récupération
  • Confirmer que les healthchecks sont verts, docker stats est stable, et les sondes applicatives réussissent.

---

Liste de contrôle opérationnelle

Utilisez cette liste lors des revues de capacité et avant les livraisons qui peuvent changer les patterns de charge.

  • Planifier un petit changement pilote inspectable et définir les métriques de succès (nombres construits acceptables pour premier passage) :
  • CPU ≤ 70% pour fenêtres stables de 10 minutes
  • Marge mémoire ≥ 25%
  • Latence p99 dans votre SLO
  • Inventorier l'environnement et les bases :
  • Enregistrer versions Docker/Compose, CPU/RAM/disque hôte
  • Capturer docker stats --no-stream pour tous les services
  • Appliquer les limites sûrement (Compose v2.4) :
  • Définir cpus, mem_limit, mem_reservation, pids_limit, et ulimits
  • Ajouter healthcheck et politiques restart
  • Monter et vérifier :
  • docker compose up -d, docker compose ps
  • docker inspect pour confirmer NanoCPUs/Memory/PIDs
  • docker stats pour usage vs limites
  • Tests de fumée applicatifs (HTTP 200, cache PING, DB prêt)
  • Exercice de charge légère :
  • Exécuter une petite rafale et observer docker stats, journaux, et latence
  • Décider de l'étape suivante :
  • Si marge adéquate, conserver limites et documenter
  • Si contraint, ajuster une limite ou ajouter un réplica ; répéter la vérification
  • Documenter les décisions :
  • Enregistrer limites finales, utilisation observée, et rationale
  • Noter chemin de retour arrière et état des sauvegardes
  • Planifier une revue de suivi :
  • Re-vérifier après heures de pointe ou lancements de fonctionnalités majeures

---

Conclusion

La planification de capacité Compose est une boucle reproductible : poser des garde-fous, vérifier, observer, et ajuster. Commencez avec un pilote étroit facile à inspecter, préférez des limites simples et explicites dans Compose v2.4, et gardez une trace claire des métriques de base et des décisions. Avec de petites itérations sûres et des signaux bien définis, vous pouvez mettre à l'échelle les services de manière prévisible tout en préservant les marges de sécurité opérationnelles. Le but n'est pas une configuration statique parfaite mais un processus discipliné qui vous laisse répondre aux patterns de charge réels sans devinettes ni lutte contre les incendies d'urgence.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO