docker ps и docker inspect
После того как ты запустил пару контейнеров, нужно уметь смотреть, что у тебя сейчас работает, и копаться в деталях. Для этого две команды: docker ps для общего обзора и docker inspect для деталей.
Эти команды ты будешь набирать десятки раз в день. Особенно docker ps, который как ls для контейнеров.
docker ps — обзор контейнеров
docker ps
Без флагов показывает только запущенные контейнеры. Пример вывода:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
abc123def456 postgres:16.4 "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:5432->5432/tcp pg
def789xyz123 nginx:alpine "/docker-entrypoint.…" 1 minute ago Up 1 minute 0.0.0.0:8080->80/tcp webby
Что в колонках:
- CONTAINER ID — короткий ID (12 символов). Полный — 64. Достаточно ID, чтобы обращаться к контейнеру в командах.
- IMAGE — из какого образа создан.
- COMMAND — что выполняется как PID 1 в контейнере. Обычно ENTRYPOINT + CMD из образа.
- CREATED — когда создан.
- STATUS —
Up 2 hoursзначит «работает уже 2 часа». Бывает:Exited (0) 5 minutes ago,Restarting,Paused. - PORTS — проброшенные порты.
0.0.0.0:5432->5432/tcpзначит «слушаем на всех интерфейсах хоста на 5432, пробрасываем в 5432 контейнера, протокол TCP». - NAMES — имя контейнера.
docker ps -a — включая остановленные
docker ps -a
Покажет все контейнеры — запущенные, остановленные, exited, dead. Это полезно, если контейнер упал и ты хочешь посмотреть, с каким кодом он вышел.
CONTAINER ID IMAGE STATUS NAMES
abc123def456 postgres:16.4 Up 2 hours pg
def789xyz123 nginx:alpine Up 1 minute webby
deadbeef0000 python:3.12 Exited (1) 5 minutes ago etl-job
Exited (1) — exit code 1, значит процесс завершился с ошибкой. Идёшь смотреть логи: docker logs etl-job.
Это, кстати, типичный отладочный workflow. Контейнер «не работает» — docker ps -a, видишь exit code, идёшь смотреть логи.
Полезные флаги ps
Фильтры
# Все остановленные с кодом не 0
docker ps -a --filter "status=exited" --filter "exited!=0"
# Все контейнеры из образа postgres
docker ps -a --filter "ancestor=postgres:16.4"
# По имени (substring match)
docker ps --filter "name=pg"
# По label
docker ps --filter "label=project=etl"
Формат
Кастомизация через --format с Go template или через table:
# Только ID и статус
docker ps --format "table {{.ID}}\t{{.Status}}\t{{.Names}}"
# JSON
docker ps --format json | jq '.'
# Только имена запущенных контейнеров
docker ps --format '{{.Names}}'
Это мощно для скриптов. Например, остановить все запущенные контейнеры:
docker stop $(docker ps -q)
Удалить все остановленные:
docker rm $(docker ps -aq --filter "status=exited")
jq, yq, JSON и YAML из командной строки
docker inspect — JSON со всем что есть
docker inspect возвращает развёрнутую JSON-структуру с конфигурацией контейнера или образа.
docker inspect pg
Вывод — JSON-массив из одного объекта. Содержит сотни полей: конфиг (Image, Cmd, Env, Volumes), сетевые настройки, монтирования, состояние, healthcheck, restart policy.
Самый полезный паттерн — извлечь конкретное поле через --format:
# Состояние контейнера
docker inspect pg --format '{{.State.Status}}'
# running
# IP-адрес внутри Docker bridge
docker inspect pg --format '{{.NetworkSettings.IPAddress}}'
# 172.17.0.2
# Запущен ли
docker inspect pg --format '{{.State.Running}}'
# true
# Exit code (если остановлен)
docker inspect pg --format '{{.State.ExitCode}}'
# 0
# Какой image
docker inspect pg --format '{{.Config.Image}}'
# postgres:16.4
# Переменные окружения
docker inspect pg --format '{{json .Config.Env}}'
# ["POSTGRES_PASSWORD=secret","POSTGRES_USER=postgres",...]
# Все монтирования
docker inspect pg --format '{{json .Mounts}}' | jq '.'
Полезный pattern для скриптов — выгрузить весь объект как JSON и работать с jq:
docker inspect pg | jq '.[0].State'
docker inspect pg | jq '.[0].HostConfig.Memory'
docker inspect pg | jq '.[0].NetworkSettings.Networks'
Что внутри inspect — ключевые секции
inspect для образа vs контейнера
docker inspect работает и для образов, и для контейнеров. Но структура немного отличается:
docker inspect postgres:16.4 --format '{{.Config.Cmd}}'
# [postgres]
docker inspect postgres:16.4 --format '{{.Architecture}}/{{.Os}}'
# arm64/linux
Для образа в .Config лежат только дефолты (Cmd, Entrypoint, Env), которые применятся при docker run. Для контейнера в .Config — фактические значения, которые были при создании.
Если есть имя, общее для контейнера и образа, Docker сам разберётся:
docker inspect postgres:16.4 # это образ
docker inspect pg # это контейнер по имени
Попробуй сам
Запусти пару контейнеров и поэкспериментируй с ps и inspect:
# 1. Запусти контейнеры
docker run -d --name pg -p 5432:5432 -e POSTGRES_PASSWORD=s postgres:16.4
docker run -d --name redis -p 6379:6379 redis:7-alpine
docker run --rm alpine sh -c 'exit 1' # упадёт с кодом 1
# 2. Смотри
docker ps
docker ps -a
docker ps -a --filter status=exited
# 3. Кастомный формат
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
# 4. Inspect отдельных полей
docker inspect pg --format '{{.State.Status}} {{.NetworkSettings.IPAddress}}'
docker inspect pg --format '{{json .Config.Env}}' | python3 -m json.tool
# 5. Прибраться
docker rm -f pg redis
Обрати внимание: контейнер, который завершился с --rm, не появится в docker ps -a — потому что --rm его удалил. Если ты запустил без --rm — он останется в exited.
Связь с другими модулями
docker inspect мы будем использовать постоянно в дальнейших модулях:
- Модуль 05 (слои):
GraphDriverпоказывает overlay2 layers контейнера. - Модуль 08 (volumes):
Mountsпоказывает все монтирования. - Модуль 09 (сети):
NetworkSettings.Networksпоказывает, к каким сетям подключён. - Модуль 14 (security):
HostConfig.SecurityOptпоказывает seccomp/AppArmor.
Привыкай к --format — это один из основных инструментов скриптинга вокруг Docker.