Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке Docker labels і для чого вони використовуються?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Docker labels** це key-value метадані, що додаєш до image, container, volume, мереж або сервісів. Самі по собі нічого не роблять, але tools (Traefik, Watchtower, Compose, моніторинг) їх читають, щоб вирішувати поведінку. ```dockerfile LABEL org.opencontainers.image.source=https://github.com/myorg/myapp LABEL maintainer="team@example.com" ``` ```bash docker run --label env=prod --label team=platform -d myapp docker ps --filter label=env=prod ``` **Головне:** labels це як Docker-об'єкти несуть метадані. Бери OCI-стандартні ключі (`org.opencontainers.image.*`) для image-метаданих. Tool-специфічні ключі (`traefik.*`, `com.docker.compose.*`) керують автоматизацією.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**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.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.