Skip to main content

Як перевірити стан, логи та метадані контейнера?

Три команди покривають усю observability-історію для одного container: docker ps для високорівневого стану, docker logs для того, що друкував застосунок, docker inspect для решти. Плюс docker stats для live-ресурсів.

Теорія

TL;DR

  • docker ps -a = поточний стан, порти, image, ім'я (one-line summary).
  • docker logs <name> = stdout + stderr container. -f для follow live, --tail N для останніх N рядків, --since 10m для time-обмежених.
  • docker inspect <name> = повний JSON config container, стану, мереж, volume, mount, env. Використовуй --format для одного поля.
  • docker stats = live CPU, пам'ять, мережа, block I/O. --no-stream для одного snapshot.
  • docker top <name> = дерево процесів всередині container.
  • docker port <name> = які host-порти мапляться на container-порти.

docker ps — швидкий стан

bash
$ docker ps -a --filter name=web CONTAINER ID IMAGE STATUS PORTS NAMES a3f9d2b8c1e4 nginx:1.27-alpine Up 5 minutes 0.0.0.0:8080->80/tcp web

Чотири колонки відповідають на більшість запитань: чи running? який image? з якого часу? які порти?

docker logs — що сказав застосунок

Daemon ловить stdout і stderr з PID 1 всередині container. docker logs їх назад читає.

bash
docker logs web # усі логи з старту (може бути великим) docker logs -f web # follow live (як tail -f) docker logs --tail 100 web # останні 100 рядків docker logs --since 10m web # останні 10 хвилин docker logs --since 2026-04-30T10:00:00 web # з timestamp docker logs -t web # prepend timestamps

Важливо: логи приходять зі stdout/stderr PID 1. Якщо твій застосунок пише у файл всередині container, docker logs його не покаже. Налаштуй застосунок логувати у stdout, щоб це працювало, це 12-factor норма.

docker inspect — все інше

Повний JSON-dump стану і config container. Без --format це 200-рядковий JSON. З --format отримуєш рівно одне поле:

bash
# Статус docker inspect --format '{{.State.Status}}' web # → running # Exit code (після виходу container) docker inspect --format '{{.State.ExitCode}}' web # → 137 # OOM-killed? docker inspect --format '{{.State.OOMKilled}}' web # → true / false # Restart count docker inspect --format '{{.RestartCount}}' web # → 3 # IP-адреса на дефолтному bridge docker inspect --format '{{.NetworkSettings.IPAddress}}' web # → 172.17.0.2 # Усі опубліковані порти docker inspect --format '{{json .NetworkSettings.Ports}}' web # → {"80/tcp":[{"HostIp":"0.0.0.0","HostPort":"8080"}]} # Mount'и docker inspect --format '{{range .Mounts}}{{.Type}}: {{.Source}} -> {{.Destination}}\n{{end}}' web

Шаблон --format використовує Go text/template. Вивід docker inspect <name> (без format) показує структуру полів, які можна таргетувати.

docker stats — live ресурси

bash
$ docker stats --no-stream CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS a3f9d2b8c1e4 web 0.01% 12.5MiB / 7.8GiB 0.16% 2.1kB / 832B 0B / 0B 5 b7e1f4d6a2b8 db 2.34% 145MiB / 7.8GiB 1.82% 18.4kB / 12.7kB 4.1MB / 0B 9

Без --no-stream оновлюється live як top. Корисно для виявлення memory leak (стабільне зростання MEM USAGE) або noisy neighbor.

docker top — дерево процесів всередині

bash
$ docker top web UID PID COMMAND root 84231 nginx: master process nginx -g daemon off; nginx 84290 nginx: worker process

Host-side view: PID це host-PID, не container PID 1. Корисно для зіставлення ps aux | grep на host з тим, що всередині.

docker port — port mapping

bash
$ docker port web 80/tcp -> 0.0.0.0:8080 80/tcp -> [::]:8080

Швидкий спосіб побачити, що відкрито, без парсингу inspect.

Типові помилки

Шукати логи у writable-шарі

bash
# НЕПРАВИЛЬНО: застосунок логує у /var/log/myapp.log всередині container $ docker exec web cat /var/log/myapp.log # ПРАВИЛЬНО: налаштувати застосунок логувати у stdout, тоді $ docker logs web

Застосунки, що логують у файли всередині container, не з'являються у docker logs. Вони ще й втрачаються при docker rm. Завжди логуй у stdout/stderr для контейнеризованих застосунків.

Забути --no-stream у скриптах

bash
# Висить вічно у скрипті (чекає live-апдейтів) $ docker stats > stats.txt # Snapshot, вихід, повернення $ docker stats --no-stream > stats.txt

docker stats за замовчуванням стрімить. У CI або скрипті завжди додавай --no-stream.

docker inspect без --format у скриптах

bash
# Громіздко, важко парсити $ docker inspect web | grep IPAddress | head -1 | awk -F'"' '{print $4}' # Чисто $ docker inspect --format '{{.NetworkSettings.IPAddress}}' web

Флаг --format саме для пропуску grep/awk-танцю.

Читати старі логи без --tail

Довгоживучий container може мати гігабайти логів. docker logs <name> (без флагів) намагається вивалити їх усі. Використовуй --tail 1000 або --since для обмеження.

Реальне застосування

  • «Чи up сервіс X?»docker ps --filter name=X --filter status=running -q. Порожній вивід = не запущений.
  • «Чому build-container вийшов?»docker logs --tail 200 build-container.
  • «На якій IP база?»docker inspect --format '{{.NetworkSettings.Networks.bridge.IPAddress}}' db.
  • «Скільки пам'яті web використовує зараз?»docker stats --no-stream web.
  • «Це OOM крашнув?»docker inspect --format '{{.State.OOMKilled}}' container.

Питання для поглиблення

Q: Чим docker logs відрізняється від docker logs -f?


A: Без -f вивалює накопичені логи і виходить. З -f (follow) стрімить нові, як tail -f. Ctrl+C, щоб зупинити.

Q: Чи можу побачити логи до того, як container рестартував?


A: Так, docker logs тримає логи через рестарти (до docker rm). Дефолтний driver (json-file) дописує у log-файл на диску, що переживає рестарт. Інші драйвери (syslog, journald, fluentd) шиппять логи зовні, у такому випадку docker logs може не працювати, перевір docker inspect --format '{{.HostConfig.LogConfig.Type}}'.

Q: Яка різниця між docker inspect і docker container inspect?


A: docker inspect загальний, працює на container, image, volume, network. docker container inspect явна форма лише для container. Однаковий вивід для container.

Q: Як побачити ліміти ресурсів, застосовані до container?


A: docker inspect --format '{{.HostConfig.Memory}} {{.HostConfig.NanoCpus}}' <name>. Пам'ять у байтах, CPU у nanoCPU (1 CPU = 1e9). Або docker stats показує use vs limit live.

Q: (Senior) Як дебажити container, що рестартується надто швидко, щоб приєднатися?


A: Кілька опцій. (1) Перевіряй docker logs --tail 200 між рестартами, навіть короткі сплески виводу зберігаються. (2) Override entrypoint sleep'ом, щоб лишався up: docker run --entrypoint sleep myimg 3600, тоді docker exec всередину. (3) Додай --restart=no, щоб крашнувся раз і лишився exited; тоді docker logs і docker inspect дають стабільний snapshot. (4) Запускай зламаний image з реальною entrypoint-командою, перенесеною у debug-shell wrapper.

Приклади

Швидкий health-check loop

bash
$ for c in web api db; do s=$(docker inspect --format '{{.State.Status}}' "$c" 2>/dev/null || echo missing) h=$(docker inspect --format '{{.State.Health.Status}}' "$c" 2>/dev/null || echo "-") echo "$c: $s ($h)" done web: running (healthy) api: running (healthy) db: running (starting)

Стан плюс health-статус для кількох container одразу. Чудово для shell-скриптів.

Tail логи з кількох сервісів у Compose

bash
$ docker compose logs -f --tail 50 # Стрім з усіх сервісів, кольоровано по імені. $ docker compose logs -f --tail 50 api db # Тільки api і db.

Compose ставить гарний multi-service tail поверх звичайного docker logs.

Перевірити, чому останній exited container помер

bash
$ docker inspect --format '{{.State.Status}} ({{.State.ExitCode}}) OOM={{.State.OOMKilled}} Err={{.State.Error}}' \ $(docker ps -alq) exited (137) OOM=true Err= # → exited з 137 (SIGKILL); OOMKilled=true → досягнуто memory-ліміту.

Чотири поля разом зазвичай вказують на причину без відкриття JSON-dump.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Коментарі

Ще немає коментарів