Je ne commence pas par docker exec. Un conteneur déjà mort n’a plus de process à joindre. Je commence par ce qu’il a dit en mourant.
docker ps -a # statut, code de sortie
docker logs web # stdout / stderr du PID 1
docker inspect web --format '{{.State.ExitCode}} {{.State.Error}} {{.State.OOMKilled}}'Les codes qu’on revoit en entretien :
ENTRYPOINT, CRLF sur un script, binaire amd64 sur ARM, CMD qui pointe vers un fichier jamais COPY.OOMKilled à true dans l’inspect. Ce n’est pas un bug métier dans docker logs.npm run build en CMD, un conteneur one-shot. Il n’est pas mort : il a terminé.Ensuite seulement : relancer avec une commande de debug (docker run --rm -it image sh) si l’image a un shell, ou docker run en remplaçant l’entrypoint pour echo / ls. Pas installer vim dans l’image de prod.
Une démarche, dans cet ordre : inspect, logs, hypothèse, reproduction. Le candidat qui tape dix restart et un exec sur un exited montre qu’il n’a pas compris le cycle de vie.
Deux causes à nommer parce qu’elles piègent encore :
ENTRYPOINT qui lance un script sans exec : le vrai serveur n’est pas PID 1, le script se termine, le conteneur sort 0.« Les logs sont vides. »
Le process n’a jamais atteint un logger, ou il bufferise stdout (Python sans -u, Java selon l’appender). Je relance avec une commande plus bête que l’app (ls, id, echo) pour valider l’image, puis je force le flush. Si OOMKilled, je lève la limite pour comprendre, je ne « mets 16 Go » comme correctif définitif.
« Ça meurt seulement avec Compose. »
Alors ce n’est probablement pas l’image : depends_on trop tôt, un nom DNS, une variable déclarée dans un fichier que le service ne charge pas. Je compare docker compose config au docker run qui marchait.