MAATRIX / Блог / Как установить и настроить Harbor на VPS

Как установить и настроить Harbor на VPS

MAATRIX

Когда команда вырастает из одного Docker Hub с общим логином, а лимиты на анонимные pull начинают резать CI/CD прямо посреди рабочего дня, встаёт вопрос о собственном реестре образов. Простой registry:2 от Docker решает задачу хранения, но не даёт ни разграничения доступа, ни сканирования на уязвимости, ни внятного веб-интерфейса. Harbor закрывает все эти пробелы сразу и разворачивается на обычном VPS за час, если знать, на какие грабли не наступать.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Harbor и когда он нужен

Harbor — открытый проект CNCF, по сути это Docker Registry, обёрнутый в слой из веб-интерфейса, RBAC, сканера уязвимостей и репликации. Из коробки вы получаете:

  • Проекты — изолированные пространства образов с собственными правами доступа (публичные и приватные).
  • RBAC — роли на уровне проекта: Project Admin, Maintainer, Developer, Guest, Limited Guest.
  • Сканирование уязвимостей через встроенный Trivy — при пуше образа или по расписанию, с возможностью блокировать pull для образов с критичными CVE.
  • Robot-аккаунты — сервисные токены для CI/CD с ограниченными правами и сроком жизни, без использования личных логинов.
  • Tag retention и garbage collection — правила автоматической очистки старых тегов и освобождения места на диске.
  • Репликацию — синхронизацию образов между несколькими Harbor или во внешние реестры (Docker Hub, ECR, GCR и др.).

Если вам нужно просто хранить пару образов для одного проекта — хватит и голого registry:2 (мы разбирали это в статье про приватный Docker Registry на VPS). Harbor оправдан, когда в команде несколько человек с разными правами доступа, когда нужен аудит того, кто и что запушил, и когда требование security-политики — не пускать в прод образы с известными уязвимостями.

Требования к серверу и подготовка

Harbor — это набор из полутора десятков контейнеров (core, portal, registry, database, redis, trivy, jobservice и другие), которые оркеструются через Docker Compose. По официальным минимальным требованиям проекта нужно:

ПрофильCPURAMДиск
Минимум2 ядра4 ГБ40 ГБ
Комфортно для команды4 ядра8 ГБ160 ГБ и более

Диск — самая частая недооценённая статья: образы копятся быстро, а Trivy держит собственную базу CVE (несколько сотен мегабайт, обновляется регулярно). На практике закладывайте диск с запасом под минимум полугодовой рост, если retention-политику ещё не настроили.

Понадобится также:

  • Отдельный домен или поддомен, например registry.example.com, с A-записью на IP сервера.
  • Ubuntu 22.04/24.04 или Debian 12 с установленным Docker и плагином Docker Compose.
  • Открытые порты 443 (HTTPS) и, опционально, 4443, если планируете подписывание образов через Notary.

Если Docker ещё не стоит, ставится стандартно:

curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker
docker compose version

Firewall настраивается через ufw — подробности в статье про настройку UFW на VPS:

sudo ufw allow OpenSSH
sudo ufw allow 443/tcp
sudo ufw enable

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

SSL-сертификат для реестра

Docker категорически не любит работать по HTTP с чужими реестрами (кроме localhost и явно прописанных insecure-registries), поэтому HTTPS для Harbor — не опция, а обязательное условие. Есть два рабочих подхода.

Вариант 1 — Harbor сам терминирует TLS. Получаете сертификат Let's Encrypt отдельно (например, через certbot в standalone-режиме, пока порт 443 ещё свободен) и указываете пути к файлам прямо в конфиге Harbor:

sudo apt install -y certbot
sudo certbot certonly --standalone -d registry.example.com

Сертификат ляжет в /etc/letsencrypt/live/registry.example.com/.

Вариант 2 — TLS терминирует внешний nginx, а Harbor слушает только HTTP на локальном порту. Это удобнее, если на сервере уже крутится nginx как reverse proxy для других сервисов и продлевать сертификаты вы предпочитаете централизованно через него. В этом случае в harbor.yml отключается https, Harbor работает на http.port: 8080, а nginx проксирует на этот порт с client_max_body_size не ниже 2G (образы бывают увесистыми) и с обязательным пробросом заголовков X-Forwarded-Proto.

Для одиночного VPS, где Harbor — единственный веб-сервис, проще и надёжнее вариант 1: меньше движущихся частей, меньше шансов словить редиректы или обрыв больших чанков при аплоаде слоёв.

Установка и первичная конфигурация

Скачайте offline-installer с страницы релизов Harbor на GitHub — уточните там актуальную версию, ниже для примера используется переменная:

export HARBOR_VERSION=v2.12.2   # замените на актуальную версию
wget https://github.com/goharbor/harbor/releases/download/${HARBOR_VERSION}/harbor-offline-installer-${HARBOR_VERSION}.tgz
tar xzvf harbor-offline-installer-${HARBOR_VERSION}.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml

Ключевые параметры в harbor.yml:

hostname: registry.example.com

https:
  port: 443
  certificate: /etc/letsencrypt/live/registry.example.com/fullchain.pem
  private_key: /etc/letsencrypt/live/registry.example.com/privkey.pem

harbor_admin_password: замените_на_сложный_пароль

database:
  password: замените_на_другой_сложный_пароль

data_volume: /data/harbor

trivy:
  ignore_unfixed: false
  skip_update: false

data_volume — каталог, куда лягут образы, база и логи; убедитесь, что он смонтирован на диск с достаточным объёмом (если у VPS есть отдельный блочный том — монтируйте его сюда). Пароли из harbor.yml используются только при первой установке — после запуска смена делается через веб-интерфейс или переменные окружения контейнера core, а не правкой файла задним числом.

Запуск установки:

sudo ./install.sh --with-trivy

Флаг --with-trivy подключает сканер уязвимостей; в части версий он идёт по умолчанию — проверьте ./install.sh --help для вашего релиза. Установка развернёт docker-compose стек и стартует его. Проверить состояние:

docker compose ps

Все контейнеры должны быть в состоянии Up (healthy). Первый вход — по адресу https://registry.example.com с логином admin и паролем, указанным в harbor_admin_password. Сразу после входа смените пароль администратора через Administration → Users.

Проекты, RBAC и сканирование уязвимостей

Создайте проект: Projects → New Project, укажите имя (например, backend) и уровень доступа — Public (pull без авторизации) или Private (нужен логин с правом Guest и выше). В настройках проекта включите:

  • Automatically scan images on push — каждый запушенный образ сразу уходит на анализ Trivy.
  • Prevent vulnerable images from running — блокирует pull образов с уязвимостями выше выбранного порога severity (Critical/High/Medium).

Роли внутри проекта назначаются точечно, без выдачи глобального admin-доступа:

РольМожет
Limited GuestТолько pull разрешённых тегов
GuestPull образов проекта
DeveloperPush и pull
MaintainerPush/pull + управление тегами, сканирование, retention
Project AdminВсё в проекте + управление участниками

Для CI/CD не используйте личные учётные записи — создавайте robot-аккаунты (Project → Robot Accounts → New Robot Account) с точечными правами (например, только push в конкретный проект) и сроком действия. Это даёт токен вида robot$backend+ci-runner с отдельным паролем, который можно отозвать, не трогая учётки людей.

Retention-политику (Project → Tag Retention) стоит настроить сразу, иначе диск незаметно съедается старыми тегами от каждого коммита CI — типичное правило: хранить последние 10 тегов на репозиторий или теги за последние 30 дней.

Работа с реестром: push, pull, CI и обслуживание

Логин с рабочей машины или из CI:

docker login registry.example.com -u 'robot$backend+ci-runner' -p '<token>'

Тегирование и пуш образа:

docker build -t registry.example.com/backend/api:1.4.0 .
docker push registry.example.com/backend/api:1.4.0

Пример шага в GitLab CI (подробнее о раннере — в статье про GitLab CI Runner на VPS):

build:
  stage: build
  script:
    - docker login $HARBOR_HOST -u "$HARBOR_ROBOT_USER" -p "$HARBOR_ROBOT_TOKEN"
    - docker build -t $HARBOR_HOST/backend/api:$CI_COMMIT_SHORT_SHA .
    - docker push $HARBOR_HOST/backend/api:$CI_COMMIT_SHORT_SHA

Из регулярного обслуживания:

  • Garbage Collection (Administration → Garbage Collection) — физически удаляет с диска слои, на которые больше не ссылается ни один тег. Без неё retention-политика просто открепляет теги, а место не освобождается. Настройте расписание, например раз в неделю по ночам.
  • Обновление базы Trivy идёт автоматически, если skip_update: false — реестр уязвимостей должен обновляться, иначе сканирование быстро теряет смысл.
  • Бэкап — Harbor не имеет встроенного snapshot-инструмента: бэкапьте каталог data_volume (образы) и дамп PostgreSQL из контейнера базы данных отдельно, либо настройте репликацию во второй Harbor как горячий резерв.
  • Обновление версии делается через официальный upgrade-скрипт проекта — прямая замена docker-compose.yml без него ломает миграции базы.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Чем Harbor лучше обычного Docker Registry?

RBAC, веб-интерфейс, сканирование уязвимостей, retention и репликация из коробки — то, что на голом registry:2 пришлось бы собирать вручную из отдельных инструментов.

Можно ли поставить Harbor без домена, по IP?

Технически да, но получить валидный Let's Encrypt сертификат для голого IP нельзя — придётся использовать самоподписанный сертификат и вручную добавлять его в доверенные на каждой машине, которая делает docker login. Для рабочего использования домен сильно упрощает жизнь.

Хватит ли 4 ГБ RAM в проде?

Для одной-двух команд с умеренным потоком CI — обычно да, это официальный минимум проекта. Если сборок много и параллельно идёт сканирование крупных образов, лучше закладывать 8 ГБ, иначе jobservice и trivy начинают конкурировать за память с базой.

Как перенести Harbor на другой сервер?

Останавливаете стек (docker compose down), переносите каталог data_volume и дамп базы на новый сервер, разворачиваете ту же версию Harbor и поднимаете стек заново — общий подход такой же, как при переносе любого Docker-проекта.

Нужен ли Notary для подписи образов?

Только если у вас есть требование supply-chain security с верификацией подписи при деплое (например, через Kubernetes admission controller). Для большинства команд достаточно сканирования уязвимостей без подписи.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →