Skip to main content

Що таке Docker labels і для чого вони використовуються?

Docker labels це довільні key-value пари, які можна додавати майже до будь-якого Docker-об'єкта. Це тихі метадані: сам Docker з ними нічого не робить, але екосистема tools навколо Docker їх читає постійно. Знання, як використовувати labels, відкриває половину сучасного Docker-tooling.

Теорія

TL;DR

  • Labels = key-value-рядки, прикріплені до image, container, volume, мереж, сервісів і Compose-стеків.
  • Ставиш у Dockerfile (LABEL), при run (--label), у Compose (labels:) або через API.
  • Docker сам не діє на labels, tools, що стежать за Docker-API.
  • Стандартні namespace:
    • org.opencontainers.image.* — OCI image-annotation (source, version, license).
    • com.docker.compose.* — встановлюються автоматично Compose.
    • traefik.* — читаються Traefik для конфігурації routing.
    • org.label-schema.* — старіша конвенція, ще зустрічається у legacy Dockerfile.
  • Фільтрувати і query'їти: docker ps --filter label=env=prod, docker images --filter label=team=platform.

Як ставити labels

У Dockerfile

dockerfile
LABEL org.opencontainers.image.source=https://github.com/myorg/myapp LABEL org.opencontainers.image.version=1.2.3 LABEL org.opencontainers.image.description="My production API" LABEL org.opencontainers.image.licenses=MIT LABEL maintainer="team@example.com" # АБО multi-line LABEL org.opencontainers.image.source=https://github.com/myorg/myapp \ org.opencontainers.image.version=1.2.3 \ maintainer="team@example.com"

Ці їдуть з image, docker inspect myimg їх показує, docker images --filter label=... знаходить.

При run

bash
docker run -d \ --label env=prod \ --label team=platform \ --label cost-center=engineering \ --name api \ myapp:1.0

Labels застосовуються до екземпляра container, не до image.

У Compose

yaml
services: api: image: myapp:1.0 labels: env: prod team: platform "traefik.http.routers.api.rule": "Host(`api.example.com`)" "traefik.http.services.api.loadbalancer.server.port": "3000"

Нота: dotted-ключі зі значеннями, що містять крапки/спец-символи, потребують лапок у YAML.

Стандартні namespace і для чого вони

OCI image-labels (стандартизовано)

org.opencontainers.image.created # ISO-timestamp білду org.opencontainers.image.authors # контакти org.opencontainers.image.url # URL документації org.opencontainers.image.documentation # docs URL org.opencontainers.image.source # URL source-repo org.opencontainers.image.version # image-semver org.opencontainers.image.revision # source git SHA org.opencontainers.image.vendor # publisher org.opencontainers.image.licenses # SPDX license-вираз org.opencontainers.image.title # human-readable ім'я org.opencontainers.image.description # коротке опис

Product image на Docker Hub, GHCR та інших registry використовують ці. Ставити їх це best practice для будь-якого image, що публікуєш.

Tool-driven labels

yaml
# Traefik — auto-routing labels: - "traefik.enable=true" - "traefik.http.routers.web.rule=Host(`api.example.com`)" - "traefik.http.services.web.loadbalancer.server.port=3000" # Watchtower — auto-update labels: - "com.centurylinklabs.watchtower.enable=true" - "com.centurylinklabs.watchtower.scope=production" # autoheal — auto-restart unhealthy labels: - "autoheal=true"

Ці tools підписуються на Docker-event і читають labels, щоб вирішити, що робити.

Автоматичні labels Compose

Compose додає ці до кожного container, що створює:

com.docker.compose.project=<project> com.docker.compose.service=<service-name> com.docker.compose.container-number=1 com.docker.compose.config-hash=<sha> com.docker.compose.oneoff=False com.docker.compose.version=<compose-version>

Фільтр Compose-стеків по них:

bash
docker ps --filter label=com.docker.compose.project=myapp

Фільтрування і querying

bash
# Container з конкретним label docker ps -a --filter label=env=prod # Container з label-ключем (будь-яке значення) docker ps -a --filter label=team # Container БЕЗ label docker ps -a --filter "label!=team=platform" # Кілька фільтрів (AND) docker ps -a --filter label=env=prod --filter label=team=api # Те саме для image, volume, мереж docker images --filter label=org.opencontainers.image.version=1.2.3 docker volume ls --filter label=backup=daily docker network ls --filter label=stack=myapp

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

Використання labels як стану

Labels це метадані, не app-стан. Не оновлюються у runtime; Docker-API трактує їх як immutable на життєвий цикл об'єкта. Якщо потрібен стан, бери базу або external store.

Класти secret у labels

yaml
# НЕПРАВИЛЬНО labels: - "db.password=hunter2"

Labels з'являються у docker inspect, ps -a і image-history. Видно кожному з read-доступом до daemon. Ніколи не клади secret у labels.

Інконсистентні label-ключі

yaml
# Погано service-1: { labels: { env: prod } } service-2: { labels: { environment: production } } service-3: { labels: { ENV: PROD } }

Фільтрування стає здогадуванням. Обери одну конвенцію (lowercase, без абревіатур, dot-separated для namespacing) і документуй.

Забути поставити OCI-labels на опубліковані image

Push image у Docker Hub або GHCR без org.opencontainers.image.* labels це втрачена можливість. Registry їх відображають; користувачі покладаються на них для пошуку source, license і version-info.

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

  • Reverse-proxy auto-routing: Traefik-labels роблять route сервісу self-describing. Додай сервіс у мережу з правильними labels, Traefik його підхоплює.
  • Auto-update: Watchtower стежить за labeled-container і тягне новіші image за розкладом.
  • Cost-allocation: label кожен container з team, cost-center, env. Monitoring-стек групує метрики по label для chargeback.
  • Backup-discovery: label volume з backup=daily; backup-скрипт перелічує по label.
  • Compliance: label image з compliance.scan-date, compliance.cve-count; фільтр для старих або вразливих image.
  • Multi-tenant cleanup: docker rm $(docker ps -aq --filter label=tenant=acme), щоб знести container одного tenant.

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

Q: Чи labels mutable?


A: Ні. Labels ставляться при створенні об'єкта і персистять на життєвий цикл об'єкта. Щоб змінити, перестворюй об'єкт.

Q: Яка різниця між Docker labels і Kubernetes labels?


A: Та сама ідея, інший scope. K8s labels first-class для selecting pod/сервіси у deployment і service. Docker labels це пасивні метадані, читаються tools. K8s також має annotations (non-selectable довільні метадані), що ближче по духу до Docker-labels.

Q: Чи можна додати labels до running container?


A: Ні. Labels ставляться на create-time. Щоб додати, перестворюй container з --label new-key=value.

Q: Який рекомендований формат для label-ключів?


A: Reverse-DNS, усе lowercase: com.example.team.env. Стандартні префікси: org.opencontainers.*, com.docker.*. Уникай uppercase, пробілів і спец-символів.

Q: (Senior) Як використати labels для multi-tenant Docker з cost-allocation?


A: Вимагай labels при admission: кожен docker run (або Compose-сервіс) потребує tenant, team, cost-center, env. Enforce через pre-deploy перевірку або admission-controller. Monitoring-стек (cAdvisor + Prometheus) бачить labels через container_label_* метрики; Grafana-дашборди групують по tenant. Billing-pipeline перелічує docker ps --filter label=tenant=... і агрегує resource-використання per tenant. Cleanup-автоматизація видаляє по label-scope. Labels це клей, що з'єднує provisioning, monitoring і accounting.

Приклади

Production-якості Dockerfile з OCI-labels

dockerfile
FROM node:22-alpine LABEL org.opencontainers.image.title="My API" LABEL org.opencontainers.image.description="Production API for myorg.com" LABEL org.opencontainers.image.source="https://github.com/myorg/myapp" LABEL org.opencontainers.image.version="1.2.3" LABEL org.opencontainers.image.licenses="MIT" LABEL org.opencontainers.image.authors="Platform Team <platform@myorg.com>" LABEL org.opencontainers.image.documentation="https://docs.myorg.com/api" WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev COPY . . USER node CMD ["node", "server.js"]

GitHub GHCR відображає це на сторінці пакета. Docker Hub робить те саме. Будь-хто, хто pull'ить image, може знайти source, license і контакти.

Compose-стек з Traefik-labels для auto-routing

yaml
services: traefik: image: traefik:v3 command: - --providers.docker - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80 ports: ["80:80", "8080:8080"] volumes: - /var/run/docker.sock:/var/run/docker.sock:ro api: image: myorg/api:1.0 labels: - "traefik.enable=true" - "traefik.http.routers.api.rule=Host(`api.example.com`)" - "traefik.http.routers.api.entrypoints=web" - "traefik.http.services.api.loadbalancer.server.port=3000" - "team=platform" - "env=prod" web: image: myorg/web:1.0 labels: - "traefik.enable=true" - "traefik.http.routers.web.rule=Host(`example.com`)" - "traefik.http.services.web.loadbalancer.server.port=80" - "team=platform" - "env=prod"

Traefik відкриває сервіси по labels; team/env labels для фільтрування і репортингу. Без nginx config-файлів, без ручних route-update.

Фільтр і clean по label

bash
# Показати усі prod-container між стеками docker ps --filter label=env=prod --format 'table {{.Names}}\t{{.Status}}' # Зупинити все labeled "team=experiments" docker stop $(docker ps -q --filter label=team=experiments) # Знайти усі image > 1 дня з конкретного source docker images --filter label=org.opencontainers.image.source=https://github.com/myorg/oldproject # Compose-проектне перелічення docker ps --filter label=com.docker.compose.project=myapp \ --format '{{.Names}} {{.Status}}'

Labels перетворюють docker ps/docker images на потужний query-tool.

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

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

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

Коментарі

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