В одной из предыдущих статей, а именно в «Применение 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 CPU |
4 CPU |
|
ОЗУ |
4 GB |
8 GB |
|
Диск |
40 GB |
160 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 и вносим изменения:
-
Удаляем блок
ports, чтобы прокси не слушал порт напрямую и был доступен только через Caddy. -
Меняем значение
container_nameнаharbor-proxy— так будет проще ориентироваться. -
В блок
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-каналу «Код на салфетке»!
ссылка на оригинал статьи https://habr.com/ru/articles/937168/
Добавить комментарий