Skip to content
VDS · Docker et conteneurs

Limites de mémoire et de CPU pour les conteneurs

Comment fixer un plafond de mémoire et de CPU pour un conteneur, pourquoi sans cela un service fait tomber tous les autres, et comment savoir qu'un processus a été tué par le noyau.

Mis à jour le 23 août 2026

Par défaut, un conteneur peut prendre toute la mémoire et tous les cœurs de la machine. Sur VDS-1 avec deux gigaoctets, cela se termine de façon prévisible : un service gonfle, le noyau commence à tuer des processus, et ce qui tombe n'est pas lui mais la base de données à côté.

Comment fixer un plafond

services:
  app:
    image: ghcr.io/example/app:1.5.0
    deploy:
      resources:
        limits:
          memory: 768M
          cpus: "1.0"
        reservations:
          memory: 256M

Compose applique deploy.resources.limits même avec un simple docker compose up -d. L'équivalent pour docker run :

docker run -d --memory 768m --cpus 1.0 --memory-swap 768m <image>

Définir --memory-swap égal à --memory interdit le swap : un crash honnête vaut mieux qu'une machine qui avance à peine pendant des heures.

Quelle quantité allouer

Partez de votre palier et laissez un peu de marge au système.

PalierMémoirePlafond total raisonnable des conteneurs
VDS-12 GBjusqu'à 1.5 GB
VDS-24 GBjusqu'à 3 GB
VDS-38 GBjusqu'à 6.5 GB
VDS-416 GBjusqu'à 14 GB
VDS-524 GBjusqu'à 21 GB
VDS-632 GBjusqu'à 29 GB

Le reste est nécessaire au système, au cache de fichiers et à Docker lui-même. Une somme de limites supérieure à la quantité de mémoire n'est pas une erreur de configuration — c'est un désastre qui attend son heure.

Pour le CPU : cpus: "1.0" correspond à un cœur complet. VDS-1 n'a qu'un seul cœur, il est donc peu utile d'y limiter le CPU, mais sur VDS-4 et au-delà, il vaut la peine d'empêcher la configuration de serveur de prendre les six.

Ce qui est réellement consommé

docker stats --no-stream
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"
free -h

Surveillez le service pendant une journée sous charge et fixez la limite à environ une fois et demie le pic. Une limite trop stricte est pire que pas de limite du tout : le service redémarrera au moment où vous en avez le plus besoin.

htop et btop en plein écran ne fonctionnent que dans la console « Screen » (VNC). La console texte ne transmet pas la taille de la fenêtre, elle fait toujours 80×24, et l'interface s'effondre. Pour des mesures rapides dans la console texte, utilisez docker stats --no-stream et free -h.

Comment savoir que la mémoire est responsable

docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' <container>
sudo dmesg -T | grep -i -E "out of memory|killed process"

Le code de sortie 137 accompagné de OOMKilled: true est un verdict sans ambiguïté. À partir de là, vous avez deux options : relever la limite si elle était trop basse, ou comprendre pourquoi l'application ne cesse de grossir — une fuite ne se soigne pas en ajoutant de la mémoire, elle est seulement repoussée.

Java et autres cas particuliers

La machine virtuelle Java voit encore parfois la mémoire de l'hôte plutôt que la limite du conteneur, et dimensionne le tas avec une marge qui n'existe pas. Définissez-la explicitement :

environment:
  JAVA_TOOL_OPTIONS: "-Xmx512m -Xms256m"

Il en va de même pour PostgreSQL (shared_buffers) et tout service disposant de son propre pool.

Erreurs courantes

  • Aucune limite définie. La cause la plus fréquente de « la machine s'est figée, rien ne répond ».
  • La limite est là, mais il n'y a pas de health check. Le conteneur a été tué et n'a jamais redémarré. Ajoutez restart: unless-stopped et un healthcheck — voir mise à jour des conteneurs.
  • Vous avez oublié le disque. Vous avez limité la mémoire, mais les écritures se heurtent à un plafond : voir vitesse du disque.