Контейнер падает сразу после старта
Порядок разбора, который закрывает большинство случаев.
Сначала — логи и код возврата
docker ps -a # статус и Exit Code
docker logs <container> # что успело написаться
docker inspect <container> --format '{{.State.ExitCode}} {{.State.Error}}'
Код возврата сразу сужает поиск:
| Код | Что обычно значит |
|---|---|
0 |
процесс завершился штатно — скорее всего, ему нечего было делать |
1 |
ошибка приложения, смотрите логи |
125 |
ошибка самого Docker (неверные аргументы) |
126 |
файл найден, но не исполняемый |
127 |
команда не найдена |
137 |
SIGKILL — почти всегда OOM |
143 |
SIGTERM — остановлен штатно |
Exit code 0: главный процесс завершился
Контейнер живёт ровно столько, сколько живёт его главный процесс. Если запустить сервис в фоне, контейнер немедленно остановится:
CMD ["nginx"] # уходит в фон → контейнер завершается
CMD ["nginx", "-g", "daemon off;"] # остаётся на переднем плане
Правило: процесс в контейнере не должен демонизироваться.
Exit code 137: не хватило памяти
docker inspect <container> --format '{{.State.OOMKilled}}'
true — контейнер вышел за лимит памяти и был убит ядром. Либо поднимите лимит, либо ограничьте потребление приложения. Для JVM и Node важно, чтобы heap был меньше лимита контейнера, иначе процесс убивают до того, как сработает сборщик мусора.
Exit code 127: команда не найдена
Обычно это разница между базовыми образами. Alpine использует musl, а не glibc: бинарник, собранный под Debian, там не запустится, хотя файл на месте. Сообщение при этом выглядит так, будто файла нет.
docker run --rm -it --entrypoint sh myimage
ls -l /app/binary
ldd /app/binary # каких библиотек не хватает
Когда логи пусты
Переопределите точку входа и посмотрите изнутри:
docker run --rm -it --entrypoint sh myimage
Дальше запускайте команду руками — ошибка станет видна. Если контейнер уже упал и нужно его состояние:
docker commit <container> debug-image
docker run --rm -it --entrypoint sh debug-image
Проверьте очевидное
Больше половины случаев — это отсутствующая переменная окружения или несмонтированный файл конфигурации:
docker inspect <container> --format '{{json .Config.Env}}' | tr ',' '\n'
docker inspect <container> --format '{{json .Mounts}}'