Процессы и диагностика

Логи и код завершения

Содержание курса

1. Где искать сообщения процесса

В предыдущем уроке фоновый запуск с флагом -d освобождал терминал, скрывая вывод выполняемой программы. Чтобы выяснить, что происходит внутри контейнера без интерактивного подключения к нему, используют встроенный журнал Docker.

Docker Engine перехватывает два стандартных потока вывода основного процесса (PID 1): стандартный вывод (stdout, дескриптор 1) и стандартный поток ошибок (stderr, дескриптор 2). Всё, что процесс отправляет в эти дескрипторы, демон Docker сохраняет во внутреннем журнале контейнера на хосте. Запись сохраняется независимо от того, работает контейнер в данный момент или уже завершился.

Проверим поведение демона на трёх изолированных процессах с разным характером завершения и вывода. В командах ниже используется запуск командной оболочки POSIX через sh -c: утилита echo выводит строку в stdout, а конструкция >&2 перенаправляет поток в stderr.

Первый процесс имитирует успешное выполнение задачи и завершается с кодом 0:

docker run --name cf_docker_course_l06_ok busybox:1.36 sh -c "echo job done; exit 0"
job done

Второй процесс намеренно выводит сообщение об ошибке в stderr и завершается с кодом 7:

docker run --name cf_docker_course_l06_err busybox:1.36 sh -c "echo 'missing CONFIG' >&2; exit 7"
missing CONFIG

Третий процесс завершается с ненулевым кодом 3, не выводя ни одного символа в консоль:

docker run --name cf_docker_course_l06_silent busybox:1.36 sh -c "exit 3"

Для чтения перехваченных потоков контейнера служит команда docker logs <container>. Она выводит накопленные записи обоих потоков (stdout и stderr) из журнала Docker.

Проверим журнал контейнера cf_docker_course_l06_ok:

docker logs cf_docker_course_l06_ok
job done

Проверим журнал завершённого контейнера cf_docker_course_l06_err:

docker logs cf_docker_course_l06_err
missing CONFIG

Docker сохранил поток stderr остановленного процесса в журнале и вывел его при запросе.

Если журнал успел накопить много строк, флаг --tail N позволяет ограничить чтение последними N записями. Запустим контейнер, создающий несколько строк вывода подряд:

docker run --name cf_docker_course_l06_tail busybox:1.36 sh -c "echo line1; echo line2; echo line3"

Запросим ровно две последние строки:

docker logs --tail 2 cf_docker_course_l06_tail
line2
line3

Флаг -f (или --follow) оставляет сессию чтения открытой: команда не завершает работу, а ожидает и в реальном времени выводит новые строки по мере их появления в stdout или stderr. Чтобы наблюдать этот механизм в действии, запустим в фоне длительный генератор логов. Команда запускает бесконечный цикл while true; do sleep 2; echo tick; done, где точка с запятой разделяет команды, sleep 2 выдерживает двухсекундную паузу, а echo tick регулярно пишет в stdout:

docker run -d --name cf_docker_course_l06_follow busybox:1.36 sh -c "echo started; while true; do sleep 2; echo tick; done"

Подключимся к чтению журнала в режиме слежения:

docker logs --follow cf_docker_course_l06_follow

В терминале сразу появится строка started, а через две секунды отобразится новое сообщение:

started
tick

Нажмите сочетание клавиш Ctrl+C, чтобы прервать чтение потока. В отличие от команды docker attach, нажатие Ctrl+C в режиме docker logs -f завершает только локальный клиент чтения логов на хосте и не отправляет сигнал остановки внутрь контейнера. Убедимся, что фоновый процесс продолжает работать:

docker inspect --format '{{.State.Status}}' cf_docker_course_l06_follow
running

Перед переходом к разбору кодов завершения остановим и удалим вспомогательный генератор логов:

docker stop cf_docker_course_l06_follow
docker rm cf_docker_course_l06_follow

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.

Логи и код завершения — Docker и Docker Compose: контейнеризация приложений — Latorn