Docker Exit Code 0: Success / Clean container shutdown — Причины остановки
Docker-контейнер запускается, но через долю секунды останавливается. В выводе команды docker ps -a контейнер находится в состоянии Exited (0). Код возврата 0 в Unix-системах означает успешное завершение работы (Success / Clean Shutdown) без ошибок, однако контейнер не продолжает работать в фоне.
| Сценарий запуска | Команда (CMD / Entrypoint) | Почему контейнер остановился (Exit 0) |
|---|---|---|
| Фоновый демон в контейнере | service apache2 start или nginx | Команда запустила фоновый процесс и успешно завершилась (PID 1 умер) |
| Запуск одноразового скрипта | python migration.py или echo hello | Скрипт выполнил все инструкции и штатно закончил работу |
| Интерактивный shell | /bin/bash или /bin/sh | Контейнер запущен без флагов -it, STDIN закрылся мгновенно |
- Команда
docker logs <container_id>не содержит ошибок и показывает нормальный вывод программы. - Контейнер перезапускается в цикле, если включена политика
restart: always.
- Главный принцип Docker: Контейнер живет ровно до тех пор, пока жив его основной процесс с PID 1. Если процесс завершается или уходит в фон (демонизируется), контейнер немедленно выключается с кодом 0.
- Запускайте серверные приложения в foreground-режиме (на переднем плане терминала), не позволяя им форкаться в фон:
# ДЛЯ APACHE: CMD ["apache2ctl", "-D", "FOREGROUND"] # или для CentOS/Alpine: CMD ["httpd", "-D", "FOREGROUND"] # ДЛЯ NGINX: CMD ["nginx", "-g", "daemon off;"] # ДЛЯ PHP-FPM: CMD ["php-fpm", "-F"] - Если вам требуется держать контейнер запущенным для отладки или работы с CLI-утилитами, запустите его с выделением псевдо-терминала (TTY) и открытого потока ввода (STDIN):
docker run -dit --name my-container ubuntu:latest /bin/bash - Если контейнер выполняет составной скрипт инициализации
entrypoint.sh, завершайте его передачей управления основному процессу черезexec:#!/bin/sh # Выполняем миграции и подготовку: ./run-migrations.sh # Заменяем PID 1 shell-скрипта на основной бинарник приложения: exec "$@" - Если контейнер используется как фоновый воркер или блокирующая задача, используйте команду ожидания:
CMD ["tail", "-f", "/dev/null"].
exec "$@" в конце shell-скрипта точки входа заменяет текущий процесс оболочки на процесс вашего приложения с сохранением PID 1. Это критически важно для корректной передачи системных сигналов остановки (SIGTERM/SIGINT) от Docker демона к вашему приложению.Частые вопросы (FAQ)
Является ли Exit Code 0 признаком аварии контейнера?
Нет. Код 0 — это стандартный код успешного выхода POSIX (Success). Он означает, что программа завершилась ровно так, как было заложено ее разработчиком.
Почему команда service nginx start выключает контейнер?
Потому что утилита service запускает Nginx в фоновом режиме (daemon) и завершает свой собственный процесс. Поскольку процесс-инициатор завершился с кодом 0, Docker считает работу контейнера завершенной.
Что означает директива restart: unless-stopped при коде 0?
Политика restart: unless-stopped или restart: always заставит Docker бесконечно перезапускать контейнер, даже если он успешно завершается с кодом 0, порождая цикл рестартов.
Как проверить точный код выхода завершенного контейнера?
Выполните команду: docker inspect <container_id> --format='{{.State.ExitCode}}'.