Пошук уроків, статей та іншого контенту
Порівняйте Docker Hub і приватні реєстри, налаштуйте автентифікацію та безпечно працюйте з доступом до образів.
Container registry — це сервіс для зберігання та поширення Docker-образів. Він приймає образи через docker push і віддає їх через docker pull.
Registry складається з репозиторіїв, у яких зберігаються різні версії образів — теги та маніфести.
Наприклад:
registry.example.com/team/catalog-api:1.4.0У цьому імені:
registry.example.com — адреса registry;
team/catalog-api — репозиторій і назва образу;
1.4.0 — тег образу.
Якщо адресу registry не вказано, Docker використовує Docker Hub:
nginx:1.27Фактично це образ із репозиторію library/nginx у Docker Hub.
Docker Hub — публічний хмарний registry, який часто використовують як стандартне джерело образів.
Він підходить для:
отримання публічних базових образів;
публікації відкритих проєктів;
зберігання приватних образів, якщо це дозволяє тариф і налаштування репозиторію;
інтеграції з CI/CD.
Приклади образів із Docker Hub:
docker pull nginx:1.27
docker pull node:22-alpine
docker pull postgres:16Публічний образ можна завантажити без автентифікації:
docker pull hello-world:latestДля публікації образу потрібні облікові дані та права запису до відповідного репозиторію.
Приватний registry доступний лише визначеним користувачам або сервісам. Він може бути:
розгорнутий всередині компанії;
наданий хмарним провайдером;
інтегрований із платформою для зберігання коду;
доступний за адресою на кшталт registry.example.com.
Приватний registry використовують, коли образи містять:
код комерційного продукту;
внутрішні сервіси;
корпоративні базові образи;
компоненти, які не можна публікувати у відкритому доступі.
Приклад імені образу:
registry.example.com/platform/orders-api:2026.09.02На відміну від Docker Hub, адресу приватного registry потрібно вказувати в імені образу.
Docker визначає registry за першою частиною імені, якщо вона містить крапку, двокрапку або має значення localhost.
nginx:1.27
docker.io/library/nginx:1.27
registry.example.com/team/api:1.0.0
localhost:5000/team/api:devПриклади:
nginx:1.27 — Docker Hub;
docker.io/library/nginx:1.27 — Docker Hub із явною адресою;
registry.example.com/team/api:1.0.0 — приватний registry;
localhost:5000/team/api:dev — registry на локальному порту 5000.
Тег є частиною адреси образу. Якщо тег не вказати, Docker використовує latest:
docker pull nginxЦе еквівалентно:
docker pull nginx:latestУ production краще вказувати конкретний тег або digest, щоб результат не змінювався неочікувано.
docker loginДля входу в Docker Hub виконайте:
docker loginDocker попросить ім’я користувача та пароль або access token.
Для іншого registry вкажіть його адресу:
docker login registry.example.comНе додавайте до адреси протокол:
# Правильно
docker login registry.example.com
# Неправильно
docker login https://registry.example.comПісля успішного входу Docker зберігає облікові дані у файлі конфігурації, зазвичай:
~/.docker/config.jsonДля автоматизації не слід використовувати основний пароль користувача. Замість нього створіть access token із мінімально необхідними правами.
Для інтерактивного входу:
docker login --username "$DOCKER_USERNAME"Коли Docker попросить пароль, введіть access token.
Для CI/CD без передачі токена через аргументи командного рядка:
printf '%s' "$DOCKER_TOKEN" | docker login \
--username "$DOCKER_USERNAME" \
--password-stdinДля приватного registry:
printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com \
--username "$REGISTRY_USERNAME" \
--password-stdinПараметр --password-stdin кращий за --password, тому що секрет не потрапляє безпосередньо до команди та списку процесів.
Після автентифікації можна завантажити приватний образ:
docker login registry.example.com
docker pull registry.example.com/team/catalog-api:1.4.0Якщо користувач не має права читання, registry поверне помилку на кшталт:
denied: requested access to the resource is deniedЦе може означати:
неправильний registry;
неправильний репозиторій;
відсутню автентифікацію;
відсутнє право pull;
помилковий тег;
прострочений або відкликаний токен.
Щоб опублікувати локальний образ у registry, його потрібно позначити повним іменем.
Наприклад, локальний образ має назву:
catalog-api:devПідготуємо тег для Docker Hub:
docker tag catalog-api:dev mydockeruser/catalog-api:1.0.0Або для приватного registry:
docker tag catalog-api:dev \
registry.example.com/team/catalog-api:1.0.0Після цього виконаємо push:
docker push registry.example.com/team/catalog-api:1.0.0Повна послідовність може виглядати так:
# Створюємо образ локально
docker build -t catalog-api:dev .
# Додаємо адресу приватного registry та версію
docker tag catalog-api:dev \
registry.example.com/team/catalog-api:1.0.0
# Виконуємо вхід у registry
printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com \
--username "$REGISTRY_USERNAME" \
--password-stdin
# Публікуємо образ
docker push registry.example.com/team/catalog-api:1.0.0Під час docker push Docker може завантажувати шари, які ще відсутні в registry. Шари, що вже є там, повторно не завантажуються.
Нижче наведено послідовність, яку можна виконати у проєкті з Dockerfile.
#!/usr/bin/env bash
set -euo pipefail
REGISTRY="registry.example.com"
IMAGE="$REGISTRY/team/catalog-api"
VERSION="${1:-1.0.0}"
: "${REGISTRY_USERNAME:?Потрібно встановити REGISTRY_USERNAME}"
: "${REGISTRY_TOKEN:?Потрібно встановити REGISTRY_TOKEN}"
# Створюємо образ із поточного каталогу
docker build -t catalog-api:local .
# Додаємо повне ім'я образу для приватного registry
docker tag "catalog-api:local" "$IMAGE:$VERSION"
# Передаємо токен через стандартний ввід
printf '%s' "$REGISTRY_TOKEN" | docker login "$REGISTRY" \
--username "$REGISTRY_USERNAME" \
--password-stdin
# Завантажуємо образ у registry
docker push "$IMAGE:$VERSION"
# Виходимо з registry у поточному Docker-конфігу
docker logout "$REGISTRY"Перед запуском потрібно встановити змінні середовища:
export REGISTRY_USERNAME="ci-publisher"
export REGISTRY_TOKEN="token-value"Скрипт очікує, що:
Docker daemon доступний;
у поточному каталозі є коректний Dockerfile;
користувач має право push до registry.example.com/team/catalog-api;
змінна REGISTRY_TOKEN не потрапляє до журналів CI.
Типові права для роботи з образами можна поділити на дві категорії:
pull — читання та завантаження образів;
push — публікація нових образів і тегів.
Для різних задач потрібні різні облікові дані:
розробнику зазвичай достатньо pull для production-образів;
CI для складання має push до конкретного репозиторію;
production-середовищу потрібен лише pull;
адміністратору можуть бути потрібні права керування репозиторіями та користувачами.
Не варто використовувати один загальний обліковий запис для всіх середовищ. Краще створювати окремі service account або токени для:
локальної розробки;
CI/CD;
staging;
production.
Якщо токен скомпрометовано, його потрібно відкликати та створити новий.
Docker може зберігати облікові дані за допомогою credential helper. Це безпечніше, ніж залишати їх у відкритому вигляді у config.json.
Конкретний спосіб залежить від операційної системи та встановлених Docker credential helpers.
Перевірити поточний Docker-конфіг можна так:
docker infoНе додавайте такі файли до Git:
~/.docker/config.json
.envЯкщо для окремої операції потрібно використовувати ізольований конфіг, задайте DOCKER_CONFIG:
export DOCKER_CONFIG="$(mktemp -d)"
printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com \
--username "$REGISTRY_USERNAME" \
--password-stdin
docker pull registry.example.com/team/catalog-api:1.0.0
# Видаляємо тимчасові облікові дані
rm -rf "$DOCKER_CONFIG"
unset DOCKER_CONFIGТакий підхід особливо корисний у тимчасових середовищах і CI.
У CI/CD секрети потрібно зберігати у захищеному сховищі змінних середовища, а не в репозиторії.
Приклад команд для job:
set -eu
# REGISTRY_USERNAME і REGISTRY_TOKEN надаються CI як захищені змінні
printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com \
--username "$REGISTRY_USERNAME" \
--password-stdin
docker build -t registry.example.com/team/catalog-api:"$CI_COMMIT_SHA" .
docker push registry.example.com/team/catalog-api:"$CI_COMMIT_SHA"
docker logout registry.example.comУ цьому прикладі тег на основі SHA коміту дає змогу однозначно визначити, з якого коміту створено образ.
Для CI важливо:
надати токену лише право push до потрібного репозиторію;
не виводити токен у логи;
не передавати секрет у docker build через звичайний ARG;
видаляти або ізолювати Docker-конфіг після завершення job;
використовувати окремий токен для кожного середовища.
Щоб видалити збережені облікові дані для Docker Hub:
docker logoutЩоб вийти з конкретного registry:
docker logout registry.example.comЦе не видаляє локальні образи. Команда видаляє облікові дані для відповідного registry з Docker-конфігурації або credential helper.
printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com \
--username "$REGISTRY_USERNAME" \
--password-stdin
docker pull registry.example.com/team/catalog-api:1.4.0docker build -t catalog-api:local .
docker tag catalog-api:local \
registry.example.com/team/catalog-api:1.5.0
docker push registry.example.com/team/catalog-api:1.5.0docker run --rm \
registry.example.com/team/catalog-api:1.4.0Для production-середовища доступ до registry має бути налаштований до запуску контейнера. Сам контейнер не повинен отримувати Docker-токен безпосередньо, якщо цього не вимагає його логіка.
Погано:
docker login --username user --password "secret"Краще:
printf '%s' "$REGISTRY_TOKEN" | docker login \
--username "$REGISTRY_USERNAME" \
--password-stdinПогано:
docker push catalog-api:1.0.0У такому випадку Docker шукатиме Docker Hub, а не приватний registry.
Правильно:
docker push registry.example.com/team/catalog-api:1.0.0Команда docker push працює з локальним образом, який має повну назву registry:
docker tag catalog-api:local \
registry.example.com/team/catalog-api:1.0.0
docker push registry.example.com/team/catalog-api:1.0.0latest як єдиної версіїТег latest може вказувати на різний вміст у різний час. Для розгортання краще використовувати версійні теги або унікальні теги комітів:
docker pull registry.example.com/team/catalog-api:1.5.0Токен із правами адміністратора небезпечно використовувати в CI. Створюйте токени з мінімальним набором дозволів і обмежуйте їх конкретним репозиторієм, якщо registry це підтримує.
Не записуйте токени у:
Dockerfile;
docker-compose.yml;
shell-скрипти;
файли .env, які комітяться;
документацію з прикладами реальних значень.
Docker Hub — готовий хмарний registry, а приватний registry обмежує доступ до образів.
Адресу приватного registry потрібно вказувати в імені образу.
Для входу використовуйте docker login.
У CI/CD передавайте токен через --password-stdin, а не через аргумент --password.
Розділяйте права pull і push, використовуйте окремі токени та service account.
Не зберігайте секрети в коді або репозиторії.
Перед docker push позначайте локальний образ повною назвою registry.
Для production використовуйте однозначні версійні теги або теги комітів замість залежності лише від latest.