n1ro°
RU

Текст и данные · Инструкция

Docker labels для контейнеров и образов

Docker labels для контейнеров и образов удобны, когда имена уже не дают достаточно контекста: окружение, владелец.

Редакция N1RO · Проверено

Короткий ответ

Как задавать labels для образов и контейнеров через LABEL, --label и Compose, читать их через inspect и фильтровать docker ps и image ls.

Как устроены labels и почему ключи лучше проектировать заранее

Label — это строковая пара ключ–значение, привязанная к Docker-объекту. Docker поддерживает labels для образов, контейнеров, сетей, volumes, daemon и объектов Swarm, но на обычных образах и контейнерах labels статичны на время жизни объекта: чтобы изменить их, объект нужно пересоздать. Это важное ограничение для автоматизации: не стоит использовать label как «живое поле статуса», если вы рассчитываете менять его каждую минуту. Для собственных ключей удобно применять обратный доменный namespace, например `com.example.owner` или `ru.n1ro.env`, чтобы не столкнуться с чужими именами. Значения сериализуются в строки; Docker не понимает вложенный JSON как структуру и не сможет фильтровать по полям внутри строки. Поэтому для часто используемых критериев лучше делать отдельные простые labels: `env=prod`, `team=backend`, `cleanup=weekly`.

Совет: Для автоматизации выбирайте короткий фиксированный словарь ключей и значений. Свободный текст в labels быстро превращается в неуправляемую таксономию.

Добавить labels к образу и контейнеру

  1. В Dockerfile добавьте метаданные образа: `LABEL com.example.version="1.4" com.example.component="api"`. Они станут частью конфигурации собранного image.
  2. Если label нужен только конкретной сборке, используйте `docker build --label "com.example.commit=$GIT_SHA" -t myapp .` и передайте значение из CI.
  3. При запуске контейнера добавьте runtime-метаданные: `docker run -d --label "com.example.env=prod" --label "com.example.owner=payments" --name api myapp`.
  4. Проверьте labels контейнера: `docker inspect --format='{{json .Config.Labels}}' api`. Для image используйте тот же inspect по имени образа.
  5. Отфильтруйте контейнеры: `docker ps --filter "label=com.example.env=prod"`. Для точного значения используйте `label=key=value`.
  6. Отфильтруйте образы: `docker image ls --filter "label=com.example.version"` или по конкретному значению, если оно известно.

Важно: В CI добавляйте commit SHA, build number или source revision как отдельные labels, но не кладите туда секреты: metadata легко читается через inspect.

Где задавать метаданные

  • Dockerfile LABEL. Версия продукта, лицензия, source URL, компонент. В образе и наследуется контейнером как часть image config
  • docker build --label. Данные конкретной сборки из CI. В собранном образе
  • docker run --label. Окружение, владелец, runtime-классификация. В конкретном контейнере
  • Compose labels. Метаданные сервисных контейнеров в проекте. В создаваемых Compose-контейнерах

Предупреждение: Labels видны тому, кто может инспектировать Docker-объекты. Не помещайте туда токены, пароли, приватные ключи и другие секреты.

Фильтрация: presence против точного значения

Фильтр `label=key` означает «покажи объекты, у которых ключ существует», а `label=key=value` — «покажи объекты с конкретным значением». Разница важна, когда вы хотите, например, найти все контейнеры, которые вообще участвуют в автоматической очистке, независимо от расписания. Команда `docker ps --filter "label=cleanup"` даст набор объектов с этим ключом, а `docker ps --filter "label=cleanup=weekly"` сузит его до еженедельной группы. Перед destructive-скриптом всегда сначала выводите список без удаления и проверяйте, что фильтр не захватывает лишние контейнеры. Для образов логика похожа: `docker image ls --filter` позволяет использовать label как критерий инвентаризации. Если нужен набор нескольких критериев, используйте несколько `--filter` или обработайте JSON вывода дополнительным инструментом. Не пытайтесь кодировать пять полей внутрь одного JSON-label и затем надеяться, что Docker разберёт его — официальная документация прямо указывает, что значения остаются строками.

Почему labels нельзя «исправить» на работающем контейнере

Для контейнеров, образов, сетей и volumes Docker считает labels статическими на протяжении жизни объекта. Это означает, что команда вроде `docker update` не предназначена для переименования или редактирования labels уже запущенного контейнера. Если вы ошиблись в `env=prod` и записали `env=prd`, корректный путь — пересоздать контейнер с правильным label, желательно из Compose или другого декларативного описания. Именно поэтому метаданные лучше хранить рядом с конфигурацией запуска, а не добавлять вручную в терминале. В Compose это особенно удобно: labels становятся частью service definition и воспроизводятся при `docker compose up` после пересоздания. Для сервисов Swarm правила отличаются — их labels могут обновляться динамически, но это уже другой объект и другой API. Не смешивайте semantics container labels и service labels в одном скрипте без явной проверки типа объекта.

Совет: Если label влияет на автоматическую очистку, мониторинг или маршрутизацию, рассматривайте его как часть конфигурационного контракта и проверяйте в CI.

Минимальная схема labels для проекта

  • `com.example.project` — устойчивое имя проекта или продукта.
  • `com.example.component` — api, worker, frontend, db-migrator и т.п.
  • `com.example.env` — dev, staging, prod с фиксированным словарём значений.
  • `com.example.version` или revision — версия артефакта, а не «latest».
  • `com.example.owner` — команда или сервис-владелец для операционных задач.
  • Отдельные automation labels — только если скрипты действительно используют их и предварительно проверяют выборку.

Важно: Не создавайте новый label для каждого запуска, если потом никто его не читает. Метаданные полезны, когда у них есть конкретный потребитель: человек, фильтр, мониторинг или автоматизация.

Пример labels, которые реально помогают в эксплуатации

Представьте сервер с десятками контейнеров нескольких команд. Вместо соглашения «по имени примерно понятно» можно закрепить `com.example.project=billing`, `com.example.env=prod` и `com.example.owner=platform`, а затем быстро получить нужную выборку фильтром. Отдельный `com.example.revision=<sha>` позволяет связать работающий контейнер с конкретной сборкой без чтения случайного тега `latest`. Для временных сред удобно иметь `com.example.lifecycle=ephemeral`, но автоматическое удаление должно дополнительно проверять возраст и окружение, а не слепо доверять одному label. Хорошая схема метаданных помогает расследовать инциденты и чистить ресурсы; плохая, где каждый инженер придумывает свои ключи, только переносит хаос из имён контейнеров в labels. Перед внедрением проверьте будущие ключи на тестовом хосте: фильтр должен выбирать ровно ожидаемые объекты и не зависеть от регистра или случайных вариантов написания.

Что учитывать

Label — это строковая пара ключ–значение, привязанная к Docker-объекту. Docker поддерживает labels для образов, контейнеров, сетей, volumes, daemon и объектов Swarm, но на обычных образах и контейнерах labels статичны на время жизни объекта: чтобы изменить их, объект нужно пересоздать. Это важное ограничение для автоматизации: не стоит использовать label как «живое поле статуса», если вы рассчитываете менять его каждую минуту. Для собственных ключей удобно применять обратный доменный namespace…

Источники и проверка

Фактическая часть сверена по первичным источникам (в т.ч. Docker object labels). Пример и формулировки — редакция N1RO на 2026-09-21.