Собственный реестр контейнеров решает три задачи: устраняет зависимость от лимитов публичных хабов, исключает утечку проприетарного кода и ускоряет выкатку в production за счет размещения образов внутри вашей сети. Вы получаете полный контроль над тем, кто и какие образы загружает, где они хранятся и как долго живут.
Это руководство проведет вас от запуска простого Docker Registry за пять минут до развертывания корпоративного Harbor с LDAP-аутентификацией и сканированием уязвимостей. Вы скопируете готовые команды, настроите SSL и получите работающий приватный реестр к концу чтения.
Зачем нужен приватный реестр и какой выбрать
Публичные реестры вроде Docker Hub вводят rate limits на скачивание, блокируют анонимные запросы и не гарантируют конфиденциальность загруженных образов. Для команды из десяти разработчиков, активно гоняющей CI/CD пайплайны, лимит в 100 pull-запросов за шесть часов исчерпывается за утренний деплой. Приватный реестр снимает это ограничение.
Выбор решения сводится к трем вариантам: Docker Registry - минималистичный и легковесный, Harbor - платформа с корпоративной безопасностью, GitLab Container Registry - встроенный инструмент для тех, кто уже использует GitLab.
Сравнение Docker Registry, Harbor и GitLab Container Registry
Docker Registry - это эталонная реализация от Docker, Inc. Он запускается одной командой, потребляет минимум ресурсов и поддерживает базовую аутентификацию через htpasswd. Встроенного веб-интерфейса нет, сканирования уязвимостей нет, репликации нет. Подходит для команд, которым нужно быстро поднять хранилище образов без дополнительной инфраструктуры.
Harbor - проект Cloud Native Computing Foundation с полноценным веб-интерфейсом, ролевой моделью (RBAC), интеграцией с LDAP и OIDC, автоматическим сканированием через Trivy и репликацией между дата-центрами. Требует Docker Compose и минимум 2 ГБ оперативной памяти. Выбор для организаций, где безопасность цепочки поставок зафиксирована в compliance-требованиях.
GitLab Container Registry встроен в GitLab и не требует отдельной установки. Каждый проект получает изолированное пространство имен, аутентификация работает через токены GitLab CI, очистка старых образов настраивается через политики тегов. Если GitLab уже развернут в компании, отдельный реестр не нужен.
| Функция | Docker Registry | Harbor | GitLab Container Registry |
|---|---|---|---|
| Аутентификация | htpasswd, токены | LDAP, OIDC, htpasswd | GitLab OAuth, токены CI |
| Сканирование уязвимостей | Нет | Trivy (встроен) | Через внешние инструменты |
| Репликация | Нет | Push/pull между инстансами | Geo (в Premium) |
| Хранение Helm-чартов | Нет | Да | Через Package Registry |
| Веб-интерфейс | Нет | Полноценный портал | Встроен в GitLab |
| Установка | Одна команда docker run | Docker Compose, 5-10 минут | Активация в gitlab.rb |
| Ресурсы (мин.) | 256 МБ RAM | 2 ГБ RAM | Зависит от GitLab |
Рекомендация: для старта и небольших команд - Docker Registry, для enterprise-среды с требованиями к аудиту и безопасности - Harbor, для экосистемы GitLab - встроенный Container Registry.
Быстрый старт: запуск Docker Registry с SSL за 5 минут
Предполагаем, что Docker установлен. Хост с IP 192.168.1.100 и доменным именем registry.example.local. Запускаем защищенный реестр с аутентификацией.
Генерация самоподписанного SSL-сертификата
Создаем директорию для сертификатов и генерируем ключ с сертификатом одной командой:
mkdir -p /opt/registry/certs && cd /opt/registry/certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout registry.key -x509 -days 365 -out registry.crt -subj "/CN=registry.example.local"Параметры: -newkey rsa:4096 - ключ RSA длиной 4096 бит, -nodes - без парольной фразы (реестр не сможет запросить пароль интерактивно), -sha256 - алгоритм подписи, -x509 - самоподписанный сертификат, -days 365 - срок действия один год.
На каждом клиенте, который будет обращаться к реестру, этот сертификат нужно добавить в доверенные. Копируем registry.crt на клиентскую машину и выполняем:
sudo cp registry.crt /usr/local/share/ca-certificates/registry.crt
sudo update-ca-certificatesДля Docker-демона на клиенте дополнительно потребуется перезапуск: sudo systemctl restart docker. Без этого шага docker login завершится ошибкой x509: certificate signed by unknown authority.
Настройка базовой аутентификации через htpasswd
Устанавливаем утилиту для генерации htpasswd-файла и создаем первого пользователя:
sudo apt install -y apache2-utils
mkdir -p /opt/registry/auth
htpasswd -Bc /opt/registry/auth/htpasswd adminФлаг -B включает bcrypt-хеширование, -c создает новый файл (при добавлении второго пользователя флаг -c опускаем, иначе файл перезапишется).
Запускаем контейнер реестра, монтируя сертификаты и файл паролей:
docker run -d \
--name registry \
--restart=always \
-p 5000:5000 \
-v /opt/registry/certs:/certs \
-v /opt/registry/auth:/auth \
-v /opt/registry/data:/var/lib/registry \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:2Проверяем работу: docker login registry.example.local:5000, вводим логин admin и пароль, затем пушим тестовый образ:
docker pull alpine:latest
docker tag alpine:latest registry.example.local:5000/alpine:latest
docker push registry.example.local:5000/alpine:latestОбраз загружен в приватный реестр. Дальше - настройка production-окружения с Harbor.
Harbor: корпоративный реестр с расширенной безопасностью
Harbor устанавливается через официальный инсталлятор, который поставляется с Docker Compose-файлом и набором контейнеров: core, portal, jobservice, registry, database, redis, trivy-adapter. Загружаем последнюю версию с GitHub:
wget https://github.com/goharbor/harbor/releases/download/v2.12.0/harbor-online-installer-v2.12.0.tgz
tar xzvf harbor-online-installer-v2.12.0.tgz
cd harbor
cp harbor.yml.tmpl harbor.ymlРедактируем harbor.yml: указываем hostname: registry.example.local, пути к SSL-сертификатам (можно использовать сгенерированные ранее или указать путь к Let's Encrypt), пароли администратора и базы данных. Запускаем установку:
sudo ./install.sh --with-trivyФлаг --with-trivy включает сканер уязвимостей. После выполнения скрипта Harbor доступен по HTTPS на порту 443. Логин в веб-интерфейс: admin / пароль из harbor.yml.
Интеграция Harbor с LDAP и OIDC
Централизованная аутентификация настраивается в разделе Administration / Configuration / Authentication. Для Active Directory заполняем поля:
Auth Mode: ldap
LDAP URL: ldaps://ad.example.local:636
LDAP Search DN: cn=admin,dc=example,dc=local
LDAP Search Password: <пароль>
LDAP Base DN: dc=example,dc=local
LDAP UID: sAMAccountNameНажимаем «Test LDAP Server» - Harbor проверит подключение и покажет список найденных пользователей. После сохранения любой сотрудник домена входит в Harbor под своей учетной записью AD.
Для OIDC (Keycloak, Okta, Azure AD) указываем:
Auth Mode: oidc
OIDC Provider Name: Keycloak
OIDC Endpoint: https://keycloak.example.local/realms/harbor
OIDC Client ID: harbor
OIDC Client Secret: <секрет>
OIDC Scope: openid,profile,email
Verify Certificate: onПосле сохранения на странице логина появляется кнопка «Login via Keycloak». Пользователи перенаправляются на форму провайдера, а после аутентификации возвращаются в Harbor с назначенной ролью.
Сканирование уязвимостей и подпись образов
Trivy в составе Harbor автоматически сканирует каждый запушенный образ. Результат виден на вкладке образа: перечень CVE с уровнями критичности. Настройка политик блокировки находится в Projects / Configuration / Policy: включаем «Prevent vulnerable images from running» и задаем порог, например, блокировать образы с Critical-уязвимостями.
Harbor поддерживает подпись образов через Notary. Для включения добавляем в harbor.yml блок notary и перезапускаем инсталлятор. После этого в настройках проекта активируется опция «Content Trust» - клиенты обязаны подписывать образы перед пушем, а Harbor проверяет подпись при приеме.
Если нужна миграция существующих образов из другого реестра, используйте пошаговое руководство по переносу Docker-образов между реестрами с проверкой целостности через digest.
GitLab Container Registry: встроенное решение для CI/CD
Если GitLab уже обслуживает репозитории кода, его Container Registry активируется одной строкой в /etc/gitlab/gitlab.rb:
registry_external_url 'https://registry.example.local'После sudo gitlab-ctl reconfigure реестр доступен по указанному домену. SSL настраивается через Let's Encrypt автоматически при указании https в URL, либо сертификаты кладутся в /etc/gitlab/ssl/ с именами registry.example.local.crt и registry.example.local.key.
Каждый GitLab-проект получает изолированное пространство имен: registry.example.local/group/project. Права на push определяются ролью пользователя в проекте: Developer и выше могут пушить образы, Guest - только pull.
Настройка GitLab CI для автоматической публикации образов
Шаблон .gitlab-ci.yml, который собирает Docker-образ и пушит его в GitLab Container Registry:
stages:
- build
- push
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
build:
stage: build
image: docker:26-dind
services:
- docker:26-dind
script:
- docker build -t $IMAGE_TAG .
- docker save $IMAGE_TAG > image.tar
artifacts:
paths:
- image.tar
push:
stage: push
image: docker:26-dind
services:
- docker:26-dind
script:
- docker load < image.tar
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $IMAGE_TAG
- docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latestПеременные $CI_REGISTRY_USER, $CI_REGISTRY_PASSWORD и $CI_REGISTRY_IMAGE GitLab предоставляет автоматически. Никаких секретов в коде - токен CI-джобы уже имеет права на push в реестр проекта.
Очистка старых образов настраивается в Settings / Packages and Registries / Cleanup policy. Правило: удалять образы старше 30 дней, оставлять минимум 5 последних тегов. GitLab запускает очистку раз в сутки.
Для интеграции с внешними CI/CD системами пригодится руководство по интеграции реестра с Jenkins, GitLab CI и GitHub Actions - там готовые конфигурации для всех трех платформ.
Устранение типичных проблем и дальнейшая эксплуатация
Самые частые ошибки при развертывании связаны с сертификатами и аутентификацией. Разберем их и способы решения.
Ошибки сертификатов и как их избежать
x509: certificate signed by unknown authority. Docker-демон не доверяет сертификату реестра. Решение: скопировать CA-сертификат в /etc/docker/certs.d/registry.example.local:5000/ca.crt на клиенте и перезапустить демон. Для Harbor и GitLab Registry путь аналогичен, порт указывается только если он нестандартный.
Для тестовых сред можно добавить реестр в insecure-registries в /etc/docker/daemon.json, но так делать в production нельзя - трафик пойдет без шифрования.
Альтернатива самоподписанным сертификатам - Let's Encrypt. Harbor поддерживает автоматическое получение сертификатов через встроенный ACME-клиент, достаточно указать https в hostname и email для уведомлений.
Очистка неиспользуемых образов и управление хранилищем
Реестр без очистки растет неограниченно. Каждый новый билд с уникальным тегом добавляет слой, и через месяц активной разработки хранилище может занять сотни гигабайт.
Для Docker Registry очистка запускается вручную:
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.ymlЭта команда удаляет манифесты, на которые нет ссылок, и пересобирает индекс. Перед запуском реестр нужно перевести в read-only или остановить - garbage collection не потокобезопасен.
Harbor управляет очисткой через политики хранения: Projects / Configuration / Tag Retention Rules. Правило «keep the most recent 10 images» оставляет 10 последних версий и удаляет остальные. Garbage collection запускается по расписанию в Administration / Garbage Collection.
GitLab Container Registry использует cleanup policy в настройках проекта. Политика срабатывает раз в сутки и удаляет теги, подпадающие под правило (например, все теги кроме latest и release-* старше 14 дней).
Для production-сред важно настроить мониторинг свободного места. Harbor предоставляет метрики Prometheus на /metrics, Docker Registry - через отдельный экспортер. Настройте алерт на заполнение диска более 80%.
Безопасность реестра не заканчивается на SSL и аутентификации. Рекомендую изучить стратегии защиты реестра от уязвимостей - там детально разобраны RBAC, шифрование хранилища и политики допуска в Kubernetes. Для комплексной защиты контейнеров на всех этапах пригодится чек-лист безопасности Docker-контейнеров 2026 с готовыми командами.
Резервное копирование реестра - это два действия: дамп конфигураций и снапшот директории с данными. Для Docker Registry это /var/lib/registry, для Harbor - том registry и база данных PostgreSQL, для GitLab - штатный механизм gitlab-backup. Проверьте, что бэкап восстанавливается, до того как он понадобится.