DevOps & CI/CD

Docker Registry

Хранилище Docker-образов: сервис, из которого серверы и кластеры скачивают образы по docker pull и куда CI кладёт их по docker push.

Что такое Docker Registry

Docker Registry (registry, реестр) — сервис хранения Docker-образов. Это то место, куда docker push отправляет собранный образ и откуда docker pull его забирает. Самый известный публичный registry — Docker Hub; именно с ним вы работаете, даже не подозревая об этом, когда пишете docker run nginx.

Терминология, которую стоит развести сразу:

  • Registry — сам сервер хранения (registry.example.com).
  • Repository — набор версий одного образа внутри registry (registry.example.com/team/api).
  • Tag — метка конкретной версии (api:1.4.2).
  • Digest — SHA256-хеш содержимого (api@sha256:2f1a…), неизменяемый идентификатор.

Полное имя образа собирается так: registry.example.com/team/api:1.4.2. Если хост не указан, Docker молча подставляет Docker Hub — отсюда nginx на самом деле означает docker.io/library/nginx:latest.

Зачем свой registry

Публичный Docker Hub не подходит, как только образы становятся вашими:

  • Приватность: в образе лежит код, а иногда и конфиги. Публичный репозиторий это раскрывает.
  • Rate limit: Docker Hub ограничивает число pull с анонимного IP. CI, скачивающий базовый образ сто раз в день, упирается в лимит и падает.
  • Скорость: pull из registry в той же сети — секунды вместо минут. Для образов с CUDA весом 5–10 ГБ разница решающая.
  • Контроль: сканирование на уязвимости, политики хранения, аудит.
  • Независимость: сборка не зависит от доступности внешнего сервиса.

Варианты

Вариант Особенность
Docker Hub Публичный, лимиты на pull, приватные репозитории платные
GitLab Container Registry Встроен в GitLab, авторизация из коробки в CI
GitHub Packages (ghcr.io) Встроен в GitHub, права наследуются от репозитория
Harbor Self-hosted, сканирование, репликация, квоты, RBAC
Distribution (registry:2) Референсная реализация, минимум функций, максимум простоты
Nexus / Artifactory Универсальные: Docker, npm, PyPI, Maven в одном месте

Поднять свой за пять минут

Минимальный registry — один контейнер:

# compose.yaml
services:
  registry:
    image: registry:2
    ports: ["5000:5000"]
    environment:
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    volumes:
      - registry-data:/var/lib/registry
      - ./auth:/auth
    restart: unless-stopped

volumes:
  registry-data:
# пароль для доступа
docker run --rm --entrypoint htpasswd httpd:2 -Bbn ci-user 'secret' > auth/htpasswd

docker login registry.example.com
docker tag api:local registry.example.com/team/api:1.4.2
docker push registry.example.com/team/api:1.4.2
docker pull registry.example.com/team/api:1.4.2

Два обязательных условия в production. TLS: Docker откажется работать с registry по HTTP — нужен SSL-сертификат, обычно через Nginx или Traefik перед registry. Диск: слои копятся быстро, каталог хранения выносят на отдельный том — образ с CUDA и PyTorch легко весит 8–12 ГБ, а версий у него десятки.

Теги: главная практическая ошибка

latest — не «последняя версия», а просто тег по умолчанию. Он подвижен: сегодня указывает на один digest, завтра на другой. Из этого следуют неприятности, которые ловят все:

  • невозможно понять, что именно работает в production;
  • откат некуда делать — предыдущего тега нет;
  • две реплики, поднятые в разное время, могут работать на разных образах.

Рабочее правило: тегировать хешем коммита и версией, а latest не использовать нигде, кроме локальных экспериментов.

docker build -t $REG/api:$CI_COMMIT_SHORT_SHA -t $REG/api:1.4.2 .
docker push --all-tags $REG/api

В Kubernetes и Swarm образ вообще стоит указывать по digest — тогда состояние однозначно и воспроизводимо.

Очистка

Registry не удаляет ничего сам, и диск однажды кончается. Удаление тега лишь снимает ссылку — слои остаются, пока не выполнена сборка мусора:

docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml

В Harbor и GitLab для этого есть политики хранения: «держать последние 10 тегов и всё, что моложе 30 дней». Настраивать их стоит сразу, а не когда диск заполнен.

Связанные термины

  • Docker Image — то, что хранится в registry
  • Docker — клиент, выполняющий push и pull
  • Dockerfile — как образ собирается перед публикацией
  • CI/CD pipeline — кладёт образы в registry
  • Kubernetes — скачивает их оттуда при деплое
  • model registry — аналогичная идея для весов моделей

Готовы запустить GPU-задачу?

Запустить GPU-сервер