Docker LinuxDocker Desktop

Docker: Контейнер не получает сигнал завершения и долго останавливается

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

Команда docker stop ждёт до истечения таймаута, затем Docker принудительно завершает процесс. Причина часто в том, что основной процесс не обрабатывает SIGTERM или запущен через оболочку, которая не передаёт сигнал.

В этой статье
  1. Как проявляется проблема и где искать причину
  2. Пошаговая диагностика и устранение
  3. Как проверить результат
  4. Если исправление не помогло

#Как проявляется проблема и где искать причину

Команда docker stop ждёт до истечения таймаута, затем Docker принудительно завершает процесс. Причина часто в том, что основной процесс не обрабатывает SIGTERM или запущен через оболочку, которая не передаёт сигнал.

Возможная причинаКак узнатьЧто делать
PID 1 — оболочкаКоманда CMD/ENTRYPOINT в shell-форме может оставить приложение дочерним процессомОсновной процесс внутри — sh или bash, а не приложениеПерейти на exec-форму запуска после тестирования
Долгое штатное завершениеСервис долго ждёт соединения или сохранения состоянияПосле SIGTERM пишет о сохранении и выходит по истечении таймаутаОценить разумный stop_grace_period и время закрытия

#Пошаговая диагностика и устранение

  1. 1. Найдите точный контейнерНа машине с Docker откройте терминал, выполните список работающих контейнеров и найдите имя нужного приложения. Сверьте столбцы STATUS и NAMES; если контейнер уже остановлен, исследуйте события старого запуска, а не останавливайте повторно.
    Linux · Терминал (Bash)Команда
    Терминал Linux/macOS или PowerShell с доступом к Docker Engine; чтение без изменения.
    docker ps --format "table {{.Names}} {{.Status}} {{.Image}}"
  1. 2. Проверьте, какой процесс получает сигналВыполните inspect, заменив ИМЯ на найденное имя. Посмотрите Path, Args, StopSignal и StopTimeout: если запуск указан через оболочку, проверьте Dockerfile и сценарий запуска в репозитории; ничего в контейнере пока не изменяйте.
  2. На Linux и Docker Desktop; замените ИМЯ названием контейнера
    Linux · Терминал (Bash)Команда
    На Linux и Docker Desktop; замените ИМЯ названием контейнера.
    docker inspect --format "{{.Path}} {{json .Args}} | signal={{.Config.StopSignal}} timeout={{.HostConfig.StopTimeout}}" ИМЯ
  1. 3. Изучите завершение в журналеОткройте последние записи; найдите сообщения о получении SIGTERM, закрытии сокетов и окончании операций. Отсутствие записей само по себе не доказывает потерю сигнала — обработчик мог не вести журнал.
  2. Логи могут содержать личные данные — перед передачей удалите секреты
    Linux · Терминал (Bash)Команда
    Логи могут содержать личные данные — перед передачей удалите секреты.
    docker logs --tail 150 --timestamps ИМЯ
  1. 4. Проверьте поведение в тестовом контейнереСоздайте копию окружения с отдельными данными и отправьте штатное завершение. Засеките время, сопоставьте его с настройкой таймаута; рабочие пользователи и операции в этот момент не должны зависеть от тестового контейнера.
  2. Только на тестовом контейнере; через 30 секунд возможен SIGKILL
    Linux · Терминал (Bash)С осторожностью
    Только на тестовом контейнере; через 30 секунд возможен SIGKILL.
    docker stop --timeout 30 ИМЯ_ТЕСТ

    Команда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.

  1. 5. Исправьте передачу сигналаВ Dockerfile образа вместо shell-формы CMD node server.js используйте exec-форму CMD ["node", "server.js"] для соответствующего приложения. Если необходим стартовый сценарий shell, завершая его, используйте exec "$@" или exec ./app после подготовительных действий; пересоберите тестовый образ.
  2. Пример только для Node.js; замените команду на реальный исполняемый файл
    Текст
    Пример только для Node.js; замените команду на реальный исполняемый файл.
    CMD ["node", "server.js"]
  1. 6. Настройте ожидание, если приложению нужно времяЕсли журнал подтвердил корректную, но долгую остановку, в Compose-файле для сервиса допускается stop_grace_period: 60s. Не ставьте бесконечное ожидание: сначала убедитесь, что приложение реагирует на сигнал.
  2. Фрагмент внутри описания сервиса Compose; влияет на время завершения
    Текст
    Фрагмент внутри описания сервиса Compose; влияет на время завершения.
    stop_grace_period: 60s
  1. 7. Повторите проверку и сравнитеЗапустите обновлённый тестовый сервис, остановите его штатно и проверьте журналы. Успех — процесс сохраняет данные и прекращает работу до таймаута без принудительного убийства. Если нет, установите обработчик SIGTERM в приложении и исследуйте блокирующие запросы.

#Как проверить результат

Контейнер завершает работу без принудительного SIGKILL, все запросы корректно закрываются, после запуска данные целы.

#Если исправление не помогло

Если процесс зависает, соберите обезличенный журнал остановки, стек зависших обработчиков и трассировку процесса в тестовом окружении. Не применяйте kill -9 к рабочей базе.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.