Docker контейнер перезапускается бесконечно: причины и решение
Пошаговое руководство по устранению бесконечного перезапуска Docker-контейнера: проверка логов, healthcheck, ресурсы, зависимости и конфигурация.
Симптомы
- Docker контейнер постоянно перезапускается (Restarting)
- docker ps показывает Restarting для контейнера
- Контейнер запускается и сразу останавливается
- docker-compose up --restart=always не помогает
- Контейнер падает с кодом выхода 1 или 137
Возможные причины
- Приложение внутри контейнера завершается с ошибкой
- Недостаточно ресурсов (RAM, CPU, диск)
- Неправильный entrypoint или CMD
- Проблемы с healthcheck
- Зависимости не готовы (БД, Redis, очередь)
- Ошибки в конфигурации приложения
Пошаговое решение
Проверьте логи контейнера
Выполните docker logs --tail 100 имя-контейнера для просмотра последних 100 строк логов. Ищите строки с ERROR, FATAL, Traceback, Exception. Логи покажут причину падения: ошибку подключения к БД, недостаток памяти, неверный конфиг. Также проверьте docker inspect имя-контейнера | grep RestartCount — это покажет количество перезапусков.
docker logs --tail 100 my-container Проверьте статус и код выхода
Выполните docker ps -a для просмотра всех контейнеров (включая остановленные). Столбец Status покажет Exited (код) — например, Exited (1) означает ошибку приложения, Exited (137) — OOM killer (нехватка RAM), Exited (139) — segmentation fault.docker inspect имя-контейнера | grep -A 5 State покажет подробности последнего запуска.
docker ps -a Проверьте ресурсы
Выполните docker stats --no-stream для просмотра потребления ресурсов. Если контейнер потребляет больше RAM, чем установлен лимит, Linux вызовет OOM killer (код 137). Увеличьте лимит в docker-compose.yml: deploy: resources: limits: memory: 2G. Также проверьте свободное место на диске: df -h — Docker не может писать логи при нехватке места.
docker stats --no-stream Проверьте entrypoint и CMD
Убедитесь, что entrypoint или CMD указывают на правильный скрипт. Выполните docker inspect имя-контейнера | grep -A 3 Entrypoint. Если entrypoint — это shell-скрипт, убедитесь, что он заканчивается exec "$@" для передачи сигналов. Проверьте, что скрипт существует внутри контейнера: docker exec имя-контейнера ls -la /app/entrypoint.sh.
docker inspect my-container | grep -A 3 Entrypoint Проверьте healthcheck
Если в docker-compose.yml или Dockerfile настроен healthcheck, контейнер может перезапускаться из-за неудачного healthcheck. Выполните docker inspect --format="{{json .State.Health}}" имя-контейнера для просмотра статуса healthcheck. Увеличьте интервал и таймаут: healthcheck: interval: 30s, timeout: 10s, retries: 3. Временно отключите healthcheck для диагностики.
docker inspect --format="{{json .State.Health}}" my-container Проверьте зависимости
Если контейнер зависит от БД или очереди, убедитесь, что они запущены и доступны. Используйте depends_on в docker-compose.yml с condition: service_healthy. Проверьте, что приложение может подключиться к зависимостям: docker exec имя-контейнера ping db. Добавьте скрипт ожидания (wait-for-it) в entrypoint для ожидания зависимостей перед запуском.
docker exec my-container ping db Запустите контейнер в интерактивном режиме
Для диагностики запустите контейнер с перезаписью entrypoint: docker run -it --entrypoint /bin/bash образ. Это позволит войти внутрь контейнера и запустить приложение вручную. Проверьте переменные окружения:env. Запустите приложение вручную: python app.js или ./start.sh — это покажет ошибку напрямую.
docker run -it --entrypoint /bin/bash my-image Исправьте перезапуск
После нахождения причины: (1) исправьте ошибку в коде или конфиге, (2) увеличьте лимиты ресурсов, (3) добавьте wait-for-it для зависимостей, (4) исправьте healthcheck. Пересоберите образ: docker-compose build --no-cache. Запустите заново: docker-compose up -d. Проверьте, что контейнер работает стабильно: docker ps.
docker-compose up -d --build restart’ accessedAt: ‘2026-06-02’ dedupe: titleHash: d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5 solutionHash: e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6 sourceHash: f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7 draft: false
Проверка статуса службы
Выполните 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 порт.
Источники
- stackoverflow.com — проверено 02.06.2026
- docs.docker.com — проверено 02.06.2026
- stackoverflow.com — проверено 02.06.2026
- docs.docker.com — проверено 02.06.2026