Контейнер у циклі перезапусків (Restarting (1) 5 seconds ago) - головний процес падає одразу після старту, а політика --restart запускає його знову.
Крок 1 - логи, включно з попередніми спробами:
docker logs --tail 100 app
docker logs --since 10m app
Найчастіші причини: помилка в конфігурації чи змінних оточення, недоступна база при старті, неіснуючий файл у CMD, помилка синтаксису після деплою.
Крок 2 - стан і причина завершення:
docker inspect app --format '{{.State.Status}} exit={{.State.ExitCode}} oom={{.State.OOMKilled}} restarts={{.RestartCount}}'
OOMKilled=true - перевищено ліміт пам'яті; код 127 - команду не знайдено; 1 - помилка застосунку.
Крок 3 - запустити образ вручну з оболонкою, обійшовши CMD:
docker run --rm -it --entrypoint sh myapp:latest
docker compose run --rm app sh
Усередині - перевірити файли, права, змінні, запустити команду вручну й побачити помилку.
Споживання ресурсів:
docker stats # CPU, пам'ять (з лімітом), мережа, диск - у реальному часі
docker stats --no-stream # одноразовий знімок
docker top app # процеси всередині контейнера
Що шукати:
- пам'ять росте й не падає - витік у довгоживучому процесі (воркер черги без
--max-jobs, Octane без--max-requests); - пам'ять близька до ліміту - скоро буде OOM; врахуйте, що в пам'ять контейнера входить і сторінковий кеш файлів;
- CPU 100% постійно - нескінченний цикл, активне очікування, надто часте опитування;
- багато процесів у
docker top- PHP-FPM з завеликимmax_childrenчи процеси-«зомбі» (немає init у PID 1).
Події Docker:
docker events --filter container=app --since 1h
Показує die, oom, kill, restart, health_status з часом - видно хронологію.
Для продакшену ручних команд замало: збір метрик (cAdvisor + Prometheus, Beszel, Netdata) і логів у централізоване сховище, сповіщення про перезапуски й OOM.
Мінімальні образи без оболонки (distroless) - для налагодження docker debug, який підключає набір інструментів до запущеного контейнера.