DevOps 9 мин чтения

Docker контейнер падает: исправление crash loop

Пошаговое руководство по устранению проблем с Docker контейнерами: анализ exit code, OOM kill, логирование, восстановление после crash loop.

Dockerконтейнерыcrashexit codeDevOps

Симптомы

  • Контейнер постоянно перезапускается (crash loop)
  • Docker контейнер завершается с exit code 1
  • Контейнер падает сразу после запуска
  • Ошибка OOMKilled при нехватке памяти
  • Контейнер работает, но health check не проходит
  • Контейнер завершается с exit code 137

Возможные причины

  • Недостаточно памяти выделено контейнеру (OOM kill)
  • Ошибка в коде приложения (unhandled exception)
  • Отсутствует конфигурационный файл или переменная окружения
  • Недоступна зависимость (база данных, API, DNS)
  • Неправильный entrypoint или cmd в Dockerfile
  • Истекло время ожидания health check

Пошаговое решение

1

Определите exit code контейнера

Exit code — главный диагностический сигнал. Выполните: docker inspect --format '{{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}' container_name. Код 137 означает SIGKILL (часто OOM kill), 139 — SIGSEGV (segfault), 143 — SIGTERM (graceful stop), 1 — общая ошибка приложения, 126/127 — проблема с командой или правами. Если exit code 137 и OOMKilled=true — контейнеру не хватает памяти.

Команда
docker inspect --format '{{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}' container_name
2

Проверьте логи контейнера

Логи содержат информацию о причине падения. Выполните: docker logs --tail 100 container_name. Ищите stack traces, ошибки подключения, сообщения о нехватке памяти. Если контейнер перезапускается слишком быстро и логи перезаписываются — приостановите перезапуск: docker update --restart=no container_name. Затем запустите вручную и изучите логи.

Команда
docker logs --tail 100 container_name
3

Проверьте потребление ресурсов

Мониторьте использование памяти и CPU: docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" container_name. Если память на пределе лимита — увеличьте его: docker update --memory=2g container_name. Для проверки OOM событий в ядре: dmesg | grep -i "oom\|killed process". Проверьте disk space: df -h /var/lib/docker/.

Команда
docker stats --no-stream
4

Проверьте конфигурацию entrypoint и cmd

Inspect entrypoint: docker inspect --format 'Entrypoint={{.Config.Entrypoint}} Cmd={{.Config.Cmd}}' container_name. Если entrypoint — shell script с set -e, любая ошибка приведёт к немедленному выходу. Проверьте скрипт: docker run --rm -it --entrypoint sh image_name. Запустите команды по одной, чтобы найти проблемную. Для long-running сервиса используйте exec в последней строке entrypoint.

Команда
docker inspect --format 'Entrypoint={{.Config.Entrypoint}} Cmd={{.Config.Cmd}}' container_name
5

Проверьте зависимости и сеть

Если логи показывают connection refused или DNS errors — проверьте доступность зависимостей изнутри контейнера: docker exec -it container_name ping db_host. Проверьте DNS: docker exec -it container_name nslookup api.service. Убедитесь, что все required services запущены. Используйте docker-compose depends_on или init containers для правильного порядка запуска.

Команда
docker exec -it container_name ping db_host
6

Увеличьте лимит памяти или исправьте утечку

Если контейнер падает из-за OOM kill — временно увеличьте лимит: docker update --memory=4g --memory-swap=4g container_name. Для JVM приложений установите heap на 75% от лимита контейнера. Если память растёт со временем — это утечка. Используйте docker stats для мониторинга. Для long-running контейнеров настройте лог ротацию: --log-opt max-size=10m --log-opt max-file=3.

Команда
docker update --memory=4g container_name
7

Восстановите после crash loop

Если контейнер в бесконечном crash loop — остановите перезапуск для анализа: docker update --restart=no container_name. Проверьте количество перезапусков: docker inspect --format '{{.RestartCount}}' container_name. Исправьте корневую причину (код, конфигурация, зависимости). Затем восстановите политику: docker update --restart=unless-stopped container_name. Для docker-compose используйте пересоздание: docker-compose up -d --force-recreate.

Команда
docker update --restart=no container_name

Контейнер в crash loop — это не самовосстановление, а проблема, требующая вмешательства. Docker restart policy маскирует корневую причину: OOM kill, segfault, ошибка конфигурации или недоступная зависимость. Ключ к решению — анализ exit code и логов.

Таблица exit codes Docker

Код 0 — нормальное завершение. Код 1 — ошибка приложения. Код 125 — ошибка Docker daemon. Код 126 — команда не является исполняемой. Код 127 — команда не найдена. Код 130 — прерывание (Ctrl+C). Код 137 — SIGKILL (часто OOM kill). Код 139 — segmentation fault. Код 143 — SIGTERM (graceful stop).

Когда контейнер падает сразу

Если контейнер завершается менее чем за 1 секунду — проблема на этапе инициализации: отсутствует конфиг, entrypoint вызывает ошибку, или не запущена зависимость. Проверьте entrypoint с помощью —entrypoint sh и запускайте команды по одной.

Профилактика

Используйте health checks для раннего обнаружения проблем. Настраивайте лимиты памяти. Используйте лог ротацию. Тестируйте entrypoint перед продакшеном. Всегда проверяйте exit code перед тем, как перезапускать контейнер.

Проверка статуса службы

Выполните systemctl status имя-службы для просмотра текущего состояния. Статус active (running) означает, что служба работает. Status failed означает ошибку. Status inactive (dead) — служба остановлена. Для подробностей: journalctl -u имя-службы -xe. Логи покажут причину падения: ошибку конфигурации, недостаток прав или конфликт портов.

Настройка автозапуска

Для автоматического запуска службы при загрузке: sudo systemctl enable имя-службы. Для запуска сейчас: sudo systemctl start имя-службы. Для отключения автозапуска: sudo systemctl disable. Проверьте зависимости: systemctl list-dependencies имя-службы. Если зависимая служба не работает, основная тоже не запустится.

Исправление конфигурации

После изменения конфигурационного файла всегда перезапускайте службу: sudo systemctl restart имя-службы. Проверьте синтаксис конфигурации: для systemd — systemd-analyze verify имя-службы.service, дляnginx — nginx -t. Синтаксические ошибки не позволяют службе запуститься.

Просмотр логов

Логи — основной инструмент диагностики. Используйте journalctl -u имя-службы для просмотра всех логов. journalctl -u имя-службы —since “1 hour ago” — за последний час. journalctl -u имя-службы -f — в реальном времени. Также проверьте /var/log/syslog или /var/log/messages для общих системных логов.

Восстановление после сбоя

Если служба упала и не запускается: sudo systemctl reset-failed имя-службы для сброса ошибки. Затем попробуйте запустить заново. Если не помогает, проверьте права доступа к файлам службы, конфигурации и логам. Убедитесь, что порт не занят другой службой: sudo ss -tlnp | grep порт.

Источники

  1. netdata.cloud — проверено 02.06.2026
  2. netdata.cloud — проверено 02.06.2026
  3. oneuptime.com — проверено 02.06.2026
  4. opslog.dev — проверено 02.06.2026