Learning Platform
Глоссарий Troubleshooting
Урок 06.04 · 22 мин
Начальный
dockerregistriesdocker-hubghcrecrharbor

Реестры образов: Docker Hub, GHCR, ECR, Harbor

Registry это сервис, который хранит образы и раздаёт их по HTTP API. До 2020 года выбор был один — Docker Hub. После того как Docker Inc ввела жёсткие rate limits на anonymous pulls, DE-команды массово начали переезжать на альтернативы: GitHub Container Registry (GHCR), AWS Elastic Container Registry (ECR), Harbor для self-hosted. Каждый со своими trade-off.

В этом уроке разберёмся, что выбрать для своих проектов, как читать image-name с учётом разных registries и почему понимание rate limits спасает CI от mysterious failures.


Что такое registry технически

Под капотом registry это веб-сервис, реализующий OCI Distribution Specification (бывший Docker Registry HTTP API V2). Это набор HTTP-эндпоинтов:

  • GET /v2/<name>/manifests/<reference> — получить манифест по тегу или digest’у
  • GET /v2/<name>/blobs/<digest> — скачать слой (blob)
  • POST /v2/<name>/blobs/uploads/ — начать загрузку нового blob’а
  • PUT /v2/<name>/manifests/<tag> — зарегистрировать манифест под тегом
  • GET /v2/_catalog — список репозиториев (опционально, не все реализуют)
  • GET /v2/<name>/tags/list — список тегов в репозитории

Любой сервис, реализующий эту спецификацию, является OCI registry. Docker Hub, GHCR, ECR, Harbor, GitLab Container Registry, Artifactory, Quay, Sonatype Nexus, локальный registry:2 от Docker — все говорят на одном языке. Это позволяет переключаться между ними без изменения CLI: docker pull ghcr.io/user/image:tag работает так же как docker pull image:tag (где skipped prefix == docker.io).

NOTE

Когда ты пишешь docker pull postgres:16, Docker подразумевает docker.io/library/postgres:16. Префикс docker.io/ это Docker Hub, library/ это official-images namespace. Для образов от других пользователей: docker pull bitnami/redis:7 означает docker.io/bitnami/redis:7. Для других registries префикс надо указывать явно: ghcr.io/apache/airflow:2.10.


Анатомия HTTP-запроса — что внутри request и response

Docker Hub: первоисточник и rate limits

Docker Hub (hub.docker.com, registry docker.io) это самый старый и большой публичный registry. Здесь живут official images (postgres, redis, python, node, ubuntu) и миллионы community-образов. Бесплатный для public images.

С ноября 2020 Docker Inc ввела rate limits на anonymous pulls:

  • Anonymous (без логина): 100 image pulls / 6 часов / IP
  • Authenticated free account: 200 pulls / 6 часов
  • Docker Pro: 5000 pulls / day
  • Docker Team / Business: unlimited

При превышении API возвращает 429 Too Many Requests. Это критично для CI: один билд с python:3.13-slim, postgres:16, redis:7, node:22 уже 4 pull’а. При параллельных билдах на shared CI-runner с общим IP лимит выгорает за минуты.

toomanyrequests: You have reached your pull rate limit.
You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit

Что делают команды:

  1. Перенос своих образов в GHCR/ECR — там нет rate limits для своего же контента
  2. Pull-through cache — локальный registry-proxy, который кэширует ответы Docker Hub, и в CI ходят туда (см. urpose nexus или harbor ниже)
  3. Authenticated pulls с команда-аккаунтаdocker login в CI с paid Docker Hub аккаунтом, лимит 5000/day
CI без кэша → Docker Hub rate limit
10 параллельных CI-job’ов с 4 pull’ами каждый = 40 pull’ов, общий IP, лимит 100/6h истекает быстро
CI Job 1CI-runner 1, pull 4 образа
CI Job 2CI-runner 2, pull 4 образа
CI Job 3CI-runner 3
...ещё 7 job'ов
pull (всё от одного IP)
Docker HubDocker Hub считает pull'ы от IP. 100 в 6 часов -- лимит. Возвращает 429 Too Many Requests.

GitHub Container Registry (GHCR)

GHCR (ghcr.io) запустился в 2020. Бесплатный для public images, нет rate limits для аутентифицированных pull’ов, привязан к GitHub-аккаунту/организации.

Адресация: ghcr.io/<owner>/<image>:<tag>. Например ghcr.io/apache/airflow:2.10.4.

Аутентификация через GitHub Personal Access Token (PAT) или внутри GitHub Actions через GITHUB_TOKEN:

echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USER --password-stdin

# Push образа
docker tag myapp:v1 ghcr.io/myorg/myapp:v1
docker push ghcr.io/myorg/myapp:v1

В GitHub Actions это вообще одна строка:

# .github/workflows/build.yml
- uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

Plus GHCR: бесплатный, без rate limits, интеграция с GitHub permissions (можно ограничить pull для private images только для определённых repo). Minus: нельзя хостить official images типа postgres — это для своих сборок и форков.


AWS Elastic Container Registry (ECR)

ECR (<account>.dkr.ecr.<region>.amazonaws.com) — managed registry для AWS workloads. Платный (плата за storage + data transfer наружу), но если ты в AWS — то data transfer в тот же regional аккаунт бесплатен.

Адресация: 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.

Особенности:

  • IAM-based аутентификация. Не пароли, а IAM-roles. В CI это aws ecr get-login-password | docker login.
  • Lifecycle policies. Можно настроить автоудаление старых тегов / untagged образов.
  • ECR Public Gallery (public.ecr.aws) — бесплатные public images типа public.ecr.aws/docker/library/postgres (зеркало Docker Hub без rate limits). Полезно для anonymous pulls в CI.
# Auth (в CI обычно через GitHub Actions aws-actions/configure-aws-credentials)
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com

# Tag и push
docker tag myapp:v1 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1

Естественный выбор для команд с EKS / ECS / Fargate. Для on-premise это просто дорого и неудобно.


Harbor: self-hosted enterprise registry

Harbor это OSS-registry, разработанный VMware (теперь под CNCF). Запускается в k8s или standalone в Docker, даёт полный контроль над хранилищем, доступом, security policies.

Что Harbor умеет помимо обычного registry:

  • Vulnerability scanning — встроенный Trivy или Clair, сканирует образы при push и в фоне
  • Image signing — Notary v2 / Cosign integration
  • Replication — двусторонняя репликация с Docker Hub / другими Harbor
  • RBAC — projects + roles (admin/maintainer/developer/guest)
  • Quotas — лимит на storage / image count per project
  • Audit log — кто и когда что push’ил

Используется в enterprise, где compliance требует self-hosted решения, либо в air-gapped environments (без интернет-доступа). Развернуть Harbor проще, чем кажется:

# Скачать installer
wget https://github.com/goharbor/harbor/releases/download/v2.13.0/harbor-online-installer-v2.13.0.tgz
tar xzf harbor-online-installer-v2.13.0.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml

# Отредактировать hostname, https-сертификат, admin-password
nano harbor.yml

# Запустить
./install.sh
# Откроется UI на https://harbor.example.com

После установки Harbor работает как OCI-registry: docker login harbor.example.com, docker push harbor.example.com/myproject/myimage:v1.


Сравнение: что выбрать

Выбор registry: сравнение по критериям для DE
Docker Hubpublic, rate-limitedFree для public images. Anonymous pulls limited 100/6h. Подходит как источник официальных образов, не как primary registry команды.
GHCRpublic/private, freeGitHub Container Registry. Бесплатно, без rate limits для auth-pulls. Естественный выбор для команд на GitHub. Не для proxying Docker Hub.
ECRAWS-native, paidAWS-managed. Платный (storage + egress), IAM-auth. Лучший выбор если инфра в AWS (EKS, ECS, Fargate). Public Gallery -- бесплатное зеркало Docker Hub без rate limits.
Harborself-hosted, full controlOSS-registry с vulnerability scanning, signing, RBAC, replication. Используется в enterprise / air-gapped. Требует операционных усилий на поддержку.

Типичный DE-stack 2026:

  • Свои образы: GHCR (если на GitHub) или ECR (если на AWS)
  • Источник официальных образов: ECR Public Gallery или pull-through cache в Harbor
  • CI без rate-limit headache: anonymous pull через GHCR-зеркало или ECR Public

Почему DE-команды переезжают с Docker Hub

Конкретные причины:

1. Rate limits ломают CI. Команда из 10 человек, 50 коммитов в день, каждый билд тянет 4 образа = 200 pull’ов с одного NAT-IP офиса. 429 errors каждый день.

2. Docker Hub Pro/Team дорогой для крупных команд. 5/user/month,при100разработчикахэто5/user/month, при 100 разработчиках это 500/mo только за registry.

3. Compliance. Регуляторика часто требует self-hosted images (банки, healthcare). Docker Hub за пределами компании это data exfiltration risk.

4. Скорость pull. В US/EU Docker Hub быстрый, в России / Азии / South America — медленный (зависит от CDN). Свой registry в том же регионе кратно быстрее.

5. Удобство приватных образов. На Docker Hub приватные репо — paid feature. На GHCR private repos бесплатно.

TIP

Универсальный паттерн для команд: для своих образов — GHCR/ECR, для официальных образов — pull-through cache или ECR Public Gallery. В docker-compose.yml для прода:

services:
  app:
    image: ghcr.io/myorg/data-pipeline@sha256:abc...
  postgres:
    image: public.ecr.aws/docker/library/postgres@sha256:def...   # без rate-limit

Попробуй сам

Посмотри на разные registries:

# Pull с Docker Hub (default)
docker pull alpine:3.21

# Pull с ECR Public (зеркало без rate limits)
docker pull public.ecr.aws/docker/library/alpine:3.21

# Сравни image IDs -- это БИТ-В-БИТ один и тот же образ
docker images | grep alpine

# Pull с GHCR (если есть public image)
docker pull ghcr.io/oven/bun:latest

# Inspect где живёт образ
docker inspect alpine:3.21 --format '{{.RepoTags}}'
docker inspect public.ecr.aws/docker/library/alpine:3.21 --format '{{.RepoTags}}'

Заметишь, что image ID (sha256) идентичен — потому что слои content-addressable, и любой registry, хостящий тот же образ, отдаст те же байты.


Проверка знанийKnowledge check
В CI-pipeline команды периодически (примерно раз в день) случается ошибка: 'toomanyrequests: You have reached your pull rate limit'. Образы используются стандартные: python:3.13-slim, postgres:16, redis:7. Какой самый простой и недорогой способ решить проблему без миграции на платный план?
ОтветAnswer
Переключить pull источника на ECR Public Gallery (public.ecr.aws/docker/library/python:3.13-slim, public.ecr.aws/docker/library/postgres:16 и т.д.). Это бесплатное anonymous-зеркало официальных образов Docker Hub без rate limits. Альтернативно -- развернуть pull-through cache (через Harbor или registry:2) на своей инфре, и направить CI на него. Третий вариант: docker login с бесплатным аккаунтом Docker Hub поднимет лимит до 200/6h, но это полумера, не решение.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Какой rate limit для anonymous pulls с Docker Hub (с одного IP)?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5