Как установить и настроить Nexus Repository на VPS
Когда в проекте появляется собственный npm-пакет, внутренний Docker-образ и пара приватных Python-библиотек, разработчики обычно заводят под каждый тип артефактов отдельный сервис — и через полгода никто не помнит, где что лежит и кто это обслуживает. Nexus Repository закрывает все эти сценарии одним инструментом: прокси для публичных реестров, приватное хранилище для своих пакетов и единая точка авторизации. Разберём, как поставить Nexus на VPS через Docker, настроить репозитории под разные форматы и закрыть его HTTPS.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Nexus Repository и когда он нужен
Nexus Repository Manager (в статье — Nexus, имеется в виду бесплатная редакция OSS от Sonatype) — универсальный менеджер артефактов. Он умеет работать в трёх ролях одновременно:
- Proxy-репозиторий — кэширует пакеты с публичных реестров (Maven Central, npmjs.org, PyPI, Docker Hub). Сборка берёт зависимости не из интернета, а из локального кэша: быстрее и не падает при недоступности внешнего реестра.
- Hosted-репозиторий — приватное хранилище для ваших собственных артефактов: внутренние библиотеки, релизные Docker-образы, npm-пакеты компании.
- Group-репозиторий — объединяет proxy и hosted в один URL, чтобы сборке не пришлось знать, откуда физически пришёл пакет.
Из коробки поддерживаются форматы Maven/Java, npm, Docker (registry v2), PyPI, а также NuGet, Raw, Go, R, APT/YUM в других вариантах. Это отличает Nexus от специализированных решений вроде Verdaccio (только npm) или простого Docker Registry (только образы) — если у вас разнородный стек, Nexus закрывает всё одним сервисом вместо трёх-четырёх.
Смысл ставить Nexus появляется, когда у команды больше одного разработчика и есть хотя бы один приватный артефакт — свой npm-пакет, внутренняя Java-библиотека или собственные Docker-образы, которые нельзя выкладывать в публичный Docker Hub. Для соло-разработчика с открытым кодом это избыточно: Nexus прожорлив по памяти и требует обслуживания. Если у вас уже есть CI-пайплайн — например, через GitLab CI — Nexus логично встраивается как хранилище для его артефактов, а рядом со SonarQube закрывает вторую половину DevOps-контура: анализ кода и хранение того, что он собрал.
Требования к серверу и подготовка ОС
Nexus написан на Java и работает поверх встроенной базы (OrientDB в старых версиях, H2/embedded в новых). Официальный минимум от Sonatype — 4 ГБ RAM для тестового стенда, но при активной работе нескольких proxy-репозиториев и Docker-реестра закладывайте от 6–8 ГБ: часть уйдёт под JVM heap, часть — под файловый кэш ОС для блобов хранилища. Диск — от 20 ГБ на старте, но растёт быстро: каждый закэшированный Docker-слой и каждая версия npm-пакета остаются на диске, пока не настроена политика очистки (об этом ниже). Для продакшена с несколькими проектами закладывайте 50+ ГБ и SSD.
Дальше — Ubuntu 24.04, root или пользователь с sudo. Первым делом поднимите базовую защиту сервера, если ещё не сделали: настройте firewall через UFW и откройте только нужные порты (SSH, 80/443, при необходимости — порт Docker-реестра). На серверах с 4 ГБ RAM и активной нагрузкой не лишним будет и swap-файл — JVM не любит OOM-killer, а с swap процесс хотя бы не убивается мгновенно при пиковой нагрузке.
Проверьте текущее потребление памяти и версию ядра перед установкой:
free -h
uname -r
Nexus официально ставится либо архивом с встроенной Java (bundled), либо контейнером — второй вариант проще в обслуживании и его будем использовать.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверУстановка через Docker
Если Docker ещё не стоит, поставьте штатным скриптом:
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
Создайте директорию под данные и volume заранее, чтобы задать владельца тома — Nexus внутри контейнера работает от непривилегированного пользователя nexus (UID 200), и без правильных прав контейнер не сможет писать в volume:
mkdir -p /opt/nexus-data
chown -R 200:200 /opt/nexus-data
Запустите контейнер:
docker run -d \
--name nexus \
--restart unless-stopped \
-p 8081:8081 \
-p 8082:8082 \
-v /opt/nexus-data:/nexus-data \
-e INSTALL4J_ADD_VM_PARAMS="-Xms2703m -Xmx2703m -XX:MaxDirectMemorySize=2703m -Djava.util.prefs.userRoot=/nexus-data/javaprefs" \
sonatype/nexus3:latest
Порт 8081 — веб-интерфейс и API, 8082 зарезервирован под первый Docker-репозиторий (позже добавите ещё порты под другие Docker-репозитории). Параметр INSTALL4J_ADD_VM_PARAMS задаёт heap JVM — ориентируйтесь на 50–60% от RAM сервера: для сервера на 8 ГБ 2.5–3 ГБ heap — разумный старт, остальное уйдёт ОС на файловый кэш.
Первый старт занимает пару минут — Nexus разворачивает базу и индексы. Следите за логом:
docker logs -f nexus
Дождитесь строки Started Sonatype Nexus OSS — до неё веб-интерфейс не ответит.
Первый запуск и базовая настройка
Веб-интерфейс живёт на порту 8081. Пока не настроили HTTPS, зайдите временно через SSH-туннель, а не голым HTTP на публичный порт:
ssh -L 8081:localhost:8081 user@your-server-ip
Откройте http://localhost:8081 в браузере. Логин по умолчанию — admin, пароль лежит в файле внутри контейнера:
docker exec nexus cat /nexus-data/admin.password
При первом входе мастер настройки попросит сменить пароль и предложит выбрать режим доступа — анонимный (гостю доступны публичные репозитории на чтение) или полностью закрытый. Для корпоративного хранилища выключайте анонимный доступ сразу: Security → Anonymous Access → Disable.
Дальше создайте отдельных пользователей и роли вместо того, чтобы раздавать всем пароль admin. Через Security → Roles заведите роль, например ci-publisher, с правами nx-repository-view-*-*-add и -edit только на нужные репозитории, и отдельного пользователя под CI с этой ролью — так утечка токена не откроет доступ ко всему хранилищу.
Настройка репозиториев: Maven, npm, Docker, PyPI
Все репозитории создаются в Repository → Repositories → Create repository. Логика одна и та же для любого формата: proxy смотрит наружу, hosted хранит ваше, group склеивает оба под одним URL.
Maven. Создайте maven2 (proxy) с URL https://repo1.maven.org/maven2/ для кэширования Maven Central, и maven2 (hosted) для своих артефактов (Version policy — Release или Mixed, если публикуете и снапшоты). Затем maven2 (group), объединяющий оба — именно его URL прописывается в settings.xml сборочной машины:
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://nexus.example.com/repository/maven-group/</url>
</mirror>
npm. Аналогично: npm (proxy) на https://registry.npmjs.org, npm (hosted) под свои пакеты, npm (group) — объединяющий. На клиенте:
npm config set registry http://nexus.example.com/repository/npm-group/
Публикация своего пакета идёт напрямую в hosted-репозиторий:
npm publish --registry http://nexus.example.com/repository/npm-hosted/
Docker. Формат чуть капризнее — каждому Docker-репозиторию (hosted, proxy) нужен отдельный HTTP-порт, потому что Docker-клиент обращается к registry по хосту и порту, а не по пути. При создании репозитория укажите HTTP или HTTPS порт (например 8082 для hosted) в блоке Docker. После создания на клиенте:
docker login nexus.example.com:8082
docker tag myapp:1.0 nexus.example.com:8082/myapp:1.0
docker push nexus.example.com:8082/myapp:1.0
Если Docker Desktop или dockerd ругается на insecure registry (нет валидного HTTPS с публичным CA), добавьте адрес в /etc/docker/daemon.json на клиентской машине:
{
"insecure-registries": ["nexus.example.com:8082"]
}
Это временная мера — в продакшене закрывайте Docker-репозиторий валидным HTTPS, тогда правка не понадобится.
PyPI. Создайте pypi (proxy) на https://pypi.org и pypi (hosted) под свои пакеты. Настройка pip.conf на клиенте:
[global]
index-url = http://nexus.example.com/repository/pypi-group/simple/
Публикация через twine:
twine upload --repository-url http://nexus.example.com/repository/pypi-hosted/ dist/*
HTTPS через Nginx и firewall
Голый HTTP на порт 8081/8082 наружу — плохая идея: логины и токены пойдут открытым текстом. Ставим Nginx как reverse proxy перед Nexus. Для веб-интерфейса и Maven/npm/PyPI трафика достаточно одного server-блока:
server {
listen 443 ssl;
server_name nexus.example.com;
ssl_certificate /etc/letsencrypt/live/nexus.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nexus.example.com/privkey.pem;
client_max_body_size 1G;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
client_max_body_size увеличен намеренно — Java-артефакты и особенно Docker-слои легко превышают дефолтный лимит Nginx в 1 МБ, и без этой строки загрузка будет обрываться ошибкой 413.
Docker-репозиторий обычно выносят на отдельный поддомен со своим server-блоком (Docker-клиент не умеет ходить по пути, только по хосту), например docker.nexus.example.com → proxy_pass http://127.0.0.1:8082. Сертификат для обоих доменов получается одной командой certbot с DNS- или HTTP-валидацией.
После того как HTTPS поднят, закройте прямой доступ к портам 8081/8082 снаружи через UFW — наружу должны смотреть только 80 и 443, а на 8081/8082 Nginx ходит по localhost:
ufw allow 80/tcp
ufw allow 443/tcp
ufw deny 8081/tcp
ufw deny 8082/tcp
Бэкапы, чистка и обслуживание
Данные Nexus — это два разных по важности набора: конфигурация с базой (кто есть кто, какие репозитории созданы) и блобы (сами файлы артефактов). Всё лежит в /opt/nexus-data, так что бэкапить проще всего весь каталог целиком, предварительно остановив контейнер, чтобы не словить артефакт в процессе записи:
docker stop nexus
tar czf /backup/nexus-$(date +%F).tar.gz -C /opt nexus-data
docker start nexus
Для минимизации простоя используйте встроенный экспорт БД (Administration → System → Database Backup, ставится по расписанию) — он снимает снапшот метаданных без остановки сервиса, а блобы можно синхронизировать rsync без остановки, так как файлы артефактов иммутабельны после публикации.
Второй момент обслуживания — рост диска. Proxy-репозитории кэшируют всё, что через них когда-либо прошло, и место не освобождается само. Настройте задачи очистки в Administration → Scheduled Tasks:
- Cleanup unused proxy repository components — удаляет закэшированные компоненты, которые давно не запрашивали.
- Compact blob store — уплотняет хранилище блобов после удаления, реально освобождая место на диске (без этого шага место из-под удалённых файлов не возвращается).
- Для Docker и npm hosted-репозиториев отдельно настраивается retention policy — например, хранить только последние N версий каждого образа/пакета.
Обновление самого Nexus через Docker — просто смена тега образа и пересоздание контейнера, данные в volume не трогаются:
docker pull sonatype/nexus3:latest
docker stop nexus && docker rm nexus
# запустить контейнер заново той же командой docker run, что и при установке
Перед крупным обновлением версии стоит свериться с release notes Sonatype — миграции схемы БД иногда необратимы, и путь назад без бэкапа закрыт.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем Nexus отличается от Docker Registry или Verdaccio?
Docker Registry и Verdaccio — узкоспециализированные решения под один формат (только образы, только npm соответственно). Nexus покрывает несколько форматов одним сервисом и одной системой авторизации, но требует больше ресурсов и настройки.
Можно ли использовать Nexus OSS в коммерческом проекте бесплатно?
Да, OSS-редакция бесплатна без ограничений по числу пользователей и репозиториев. Платная Pro-версия добавляет HA, репликацию между дата-центрами, поддержку большего числа форматов (Helm, Conan) и SLA от Sonatype.
Почему контейнер падает сразу после старта?
Чаще всего — нет прав на /opt/nexus-data (не сделали chown 200:200) или не хватает памяти под JVM heap. Проверьте docker logs nexus — там обычно явно указана причина.
Нужен ли отдельный порт для каждого Docker-репозитория?
Да, если создаёте несколько Docker hosted/proxy репозиториев — каждому нужен свой HTTP-порт, потому что Docker-клиент авторизуется по адресу хост:порт, а не по пути внутри одного порта.
Как перенести Nexus на другой сервер?
Остановить контейнер, скопировать /opt/nexus-data целиком на новый сервер (сохранив владельца 200:200), запустить контейнер той же версии образа. Апгрейд версии в процессе переноса делать не стоит — сначала перенесите, потом обновляйте на новом месте.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →