Cat

Harbor: Docker Registry на своём сервере

Пошаговое руководство по установке и настройке Harbor — self-hosted Docker Registry с интеграцией сканера уязвимостей Trivy. Узнайте, как развернуть собственный реестр Docker-образов, настроить безопасность, управление проектами и автоматическую проверку контейнеров.

Все статьи

Icon Link
Применение Docker proDream 14 Август 2025 Просмотров: 40

В одной из предыдущих статей, а именно в «Применение Portainer в CI/CD процессах», мы разобрались, что такое сборка Docker-образов и какие существуют варианты их хранения. В том примере использовался GitHub Docker Registry, а в своей работе я применяю хранилище в собственном Git-хостинге на базе Gitea.

Альтернативой хранению образов рядом с кодом является самостоятельный (self-hosted) репозиторий образов, например Harbor.

В этой статье мы разберём, что такое Harbor, как установить его на свой сервер и как начать им пользоваться.

Если вам нравятся подобные материалы, подписывайтесь на наш Telegram-канал «Код на салфетке»!


 

Что такое Harbor?

Harbor — это open-source решение для хранения Docker-образов на собственном сервере (self-hosted). Оно активно используется как в небольших проектах, так и в корпоративном сегменте. Дополнительно Harbor интегрируется с Trivy, который выполняет сканирование образов на наличие уязвимостей.

 

Ключевые особенности

  • UI и API для управления репозиториями образов.
  • RBAC — разграничение прав на уровне проектов, пользователей и групп.
  • Аутентификация и SSO (LDAP, OIDC, Keycloak и т.д.).
  • Поддержка различных типов артефактов — не только контейнеров, но и Helm-чартов, OCI-артефактов и других.
  • Встроенный прокси-кэш для зеркалирования внешних регистри.
  • Встроенный сканер уязвимостей (Trivy).
  • Репликация образов между несколькими инстансами Harbor.
  • Подпись и проверка образов через Notary.
  • Аудит-лог действий пользователей.
  • Многоуровневая политика хранения (retention policies).

 

Системные требования

 МинимальноРекомендовано
ЦПУ2 CPU4 CPU
ОЗУ4 GB8 GB
Диск40 GB160 GB

 

Что такое Trivy

Trivy — это open-source сканер уязвимостей и ошибок конфигурации (misconfig) от Aqua Security. Он умеет проверять:

  • Образы контейнеров — как ОС-пакеты, так и зависимости приложений (npm, pip, Go, Java, Ruby и т.д.).
  • Файловые системы и репозитории — ищет уязвимые зависимости прямо в коде проекта.
  • Kubernetes и IaC-манифесты — Helm, Kubernetes, Terraform и другие, на предмет небезопасных настроек.
  • SBOM — читает и генерирует SPDX/CycloneDX, а также сканирует зависимости по готовому SBOM-файлу.
  • Секреты — базовый поиск «утёкших» ключей и токенов в коде.

 

Как Trivy интегрирован в Harbor

Trivy в Harbor интегрирован как отдельный сервис-адаптер, который:

  • Сканирует образы вручную по запросу или автоматически при push (если включена эта функция).
  • Сохраняет отчёт по CVE с классификацией уязвимостей по уровням LOW / MEDIUM / HIGH / CRITICAL.
  • Позволяет задать политику блокировки pull (например, запрет на загрузку образов с уязвимостями уровня High и выше).
  • Поддерживает allowlist (игнор-лист) на уровне проекта.

 

Деплой Harbor

Приступим к установке Harbor на собственный сервер.

Что понадобится:

  • Домен второго или третьего уровня.
  • VPS, соответствующий системным требованиям.
  • Reverse-proxy — в моём случае это будет Caddy.

 

Конфигурация Harbor

Подключаемся к серверу по SSH, создаём директорию и переходим в неё:

mkdir harbor && cd harbor

Скачиваем установщик. Возьмём последнюю актуальную версию — 2.13.2:

curl -LO https://github.com/goharbor/harbor/releases/download/v2.13.2/harbor-online-installer-v2.13.2.tgz

Распаковываем архив и переходим в директорию:

tar xzf harbor-online-installer-v2.13.2.tgz && cd harbor

Переименовываем пример конфигурационного файла и открываем его для редактирования:

cp harbor.yml.tmpl harbor.yml && nano harbor.yml

Изменяем следующие параметры:

  • hostname — указываем домен без https://.
  • https — закомментируем весь блок, так как SSL-сертификат и обработку HTTPS в нашем случае будет обеспечивать Caddy.
  • external_url — раскомментируем параметр и укажем домен с префиксом https, например: https://<ваш_домен>
  • harbor_admin_password — зададим сложный пароль администратора Harbor.
  • database.password — укажем пароль для базы данных.

Остальные параметры можно оставить по умолчанию или адаптировать под свои нужды.

Сохраняем изменения (CTRL+S) и выходим из редактора (CTRL+X).

Запускаем генерацию конфигурационных файлов с включённым Trivy:

sudo ./prepare --with-trivy

На этом этапе будут загружены и подготовлены необходимые конфигурационные файлы.

 

Правки docker-compose.yml

Так как у меня Caddy работает в отдельном Docker Compose, Harbor нужно подключить к той же сети, что и Caddy.

Открываем файл для редактирования:

nano docker-compose.yml

В самом конце, в блоке networks, добавляем внешнюю сеть:

networks:
  harbor:
    external: false
  caddy_net:
    name: caddy_net
    external: true

Далее находим сервис proxy и вносим изменения:

  1. Удаляем блок ports, чтобы прокси не слушал порт напрямую и был доступен только через Caddy.
  2. Меняем значение container_name на harbor-proxy — так будет проще ориентироваться.
  3. В блок networks добавляем внешнюю сеть — в моём случае это caddy_net.

 

Настройка Caddy

Открываем Caddyfile и добавляем проксирование на nginx Harbor:

<ваш_домен> {
    encode {
        gzip
    }

    header {
        X-Content-Type-Options "nosniff"
    }

    reverse_proxy harbor-proxy:8080
}

Так Caddy будет обрабатывать входящие HTTPS-запросы и передавать их на Harbor.

 

Запуск

Для запуска выполняем команду:

docker compose up -d

Дожидаемся, пока скачаются образы и запустятся все контейнеры.

Когда Harbor будет запущен, открываем в браузере адрес вашего домена.

Если всё прошло успешно, вас встретит страница с формой входа — значит, установка завершена и сервис готов к работе.

 


 

Проект и отправка образа

Деплой прошёл успешно, теперь создадим проект и загрузим в него Docker-образ.

 

Что такое проект в Harbor?

В Harbor проект — это отдельное пространство для хранения артефактов (Docker-образов, Helm-чартов и др.), с собственными настройками доступа, политиками хранения и сканирования.

Проекты позволяют:

  • Разделять образы по приложениям, командам или окружениям (dev, staging, prod).
  • Настраивать права доступа для отдельных пользователей или групп.
  • Включать или отключать автоматическое сканирование уязвимостей.
  • Управлять retention-политикой (удаление старых или неиспользуемых образов).

Это удобно, когда в одном Harbor работают сразу несколько команд или сервисов.

 

Создание проекта

В левом меню переходим в раздел "Projects" — откроется страница со списком проектов.

 

По умолчанию уже есть проект library, но мы создадим свой. Нажимаем кнопку "New project".

 

В появившемся окне заполняем поля:

  • Название проекта — обязательно в нижнем регистре.
  • Уровень доступа — публичный или приватный.
  • Лимит дискового пространства — в гигабайтах или -1 для отключения лимита.
  • Переключатель Proxy Cache — при включении, если образа нет в вашем реестре, Harbor попытается получить его из другого источника и сохранить локально. Это удобно для часто используемых образов, но перед этим в разделе "Registries" нужно добавить источники.

После заполнения нажимаем "Ok" — проект появится в списке.

 

Переходим в созданный проект — откроется страница реестра с набором функций.

 

Чтобы получить подсказки по отправке образов, нажмите "PUSH COMMAND".

 

Здесь же указан адрес проекта в формате:

<ваш_домен>/<ваш_проект>/<название_образа>

 

Отправка образа в репозиторий

Для примера я воспользуюсь CI/CD-конфигурацией из статьи «Применение Portainer в CI/CD процессах».

Изначально у нас было так:

- name: Log in to GitHub Container Registry  
  uses: docker/login-action@v3  
  with:  
    registry: ghcr.io  
    username: ${{ github.actor }}  
    password: ${{ secrets.GITHUB_TOKEN }}  

- name: Build and push Docker image  
  uses: docker/build-push-action@v6  
  with:  
    context: .  
    push: true  
    cache-from: type=registry,ref=ghcr.io/prodreams/tempproject:latest  
    cache-to: type=inline  
    tags: |  
      ghcr.io/prodreams/tempproject:latest    
      ghcr.io/prodreams/tempproject:${{ github.sha }}

Чтобы отправлять образы в Harbor, нужно заменить адреса и реквизиты на новые:

- name: Log in to Harbor Registry  
  uses: docker/login-action@v3  
  with:  
    registry: <ваш_домен>/<ваш_проект>  
    username: ${{ secrets.HARBOR_USER }}  
    password: ${{ secrets.HARBOR_PASSWORD }}  

- name: Build and push Docker image  
  uses: docker/build-push-action@v6  
  with:  
    context: .  
    push: true  
    cache-from: type=registry,ref=<ваш_домен>/<ваш_проект>/tempproject:latest  
    cache-to: type=inline  
    tags: |  
      <ваш_домен>/<ваш_проект>/tempproject:latest    
      <ваш_домен>/<ваш_проект>/tempproject:${{ github.sha }}

Полный пример доступен в репозитории на GitHub: https://github.com/proDreams/tempProject.

После внесения изменений отправляем коммит в репозиторий и ждём завершения сборки образа:

 

Проверяем, что образ появился в репозитории Harbor:

 

Перейдя внутрь образа, можно запустить проверку на уязвимости (или включить автоматическую проверку в настройках проекта). В отчёте отобразятся все найденные уязвимости с указанием их уровня опасности:

 


 

Заключение

Harbor — это мощное и удобное решение для организации собственного Docker Registry, которое подойдёт как для небольших команд, так и для крупных компаний. Я лично планирую перенести в него все свои образы и настроить гибкое распределение доступов.

Мир open-source решений постоянно развивается, и впереди ещё множество интересных инструментов, которые можно опробовать и внедрить в свои продакшн-процессы.

А если вы хотите узнавать о таких инструментах и лучших практиках их применения — присоединяйтесь к нашему Telegram-каналу «Код на салфетке»!

Автор

    Нет комментариев