Що таке 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
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
docker run -d \
--label env=prod \
--label team=platform \
--label cost-center=engineering \
--name api \
myapp:1.0Labels застосовуються до екземпляра container, не до image.
У Compose
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
# 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-стеків по них:
docker ps --filter label=com.docker.compose.project=myappФільтрування і querying
# 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
# НЕПРАВИЛЬНО
labels:
- "db.password=hunter2"Labels з'являються у docker inspect, ps -a і image-history. Видно кожному з read-доступом до daemon. Ніколи не клади secret у labels.
Інконсистентні label-ключі
# Погано
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
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
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
# Показати усі 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.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів