Nexus Repository на сервере: частые ошибки и решения
Nexus Repository удобен именно тем, что закрывает Maven, npm, Docker и PyPI одним сервисом — но именно поэтому у него столько разных точек отказа. Сегодня падает джоба в CI, потому что push в Docker-репозиторий вернул 401, завтра сам Nexus не встаёт после рестарта с OutOfMemoryError в логе, послезавтра диск на сервере внезапно кончился, хотя вы вроде ничего крупного не заливали. Разберём эти ситуации по схеме «симптом — причина — решение», с командами и конкретными файлами конфигурации.
Содержание
- С чего начинать диагностику Nexus Repository
- Nexus не стартует или падает: OutOfMemoryError
- 401/403 при публикации в Maven, npm, PyPI
- Docker-репозиторий не пробрасывается через реверс-прокси
- Диск переполнен: blob-хранилища и cleanup policies
- Proxy-репозиторий не тянет пакеты у апстрима
- Nexus не выдерживает нагрузку CI/CD и тормозит
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →С чего начинать диагностику Nexus Repository
Прежде чем чинить что-то конкретное, убедитесь, что сам процесс жив и на что он жалуется. Три источника правды: статус сервиса, лог приложения и служебный REST-эндпоинт.
systemctl status nexus
tail -100 /opt/sonatype-work/nexus3/log/nexus.log
curl -s http://127.0.0.1:8081/service/rest/v1/status
Пустой ответ 200 OK от /service/rest/v1/status означает, что ядро Nexus поднялось и готово принимать запросы — тогда проблема, скорее всего, не в самом Nexus, а в реверс-прокси, авторизации конкретного репозитория или сети. Если статус недоступен вообще, смотрите nexus.log: там почти всегда явно написано, что пошло не так — нехватка памяти, занятый порт, повреждённый файл конфигурации. Отдельно держите в уме, где что лежит: рабочие данные (база, blob-хранилища, логи) — в /opt/sonatype-work/nexus3, сам дистрибутив с бинарниками — отдельно в /opt/nexus. Это разделение важно при обновлениях и бэкапах: обновлять можно дистрибутив, не трогая данные.
Nexus не стартует или падает: OutOfMemoryError
Самая частая причина отказа — банальная нехватка памяти. Nexus — Java-приложение на встроенном OrientDB/H2 и Jetty, и ему по умолчанию выделяется фиксированный размер кучи, который на маленьком VPS может просто не влезть в физическую память. В логе это выглядит так:
java.lang.OutOfMemoryError: Java heap space
или процесс падает молча, а dmesg показывает, что OOM killer убил java из-за нехватки RAM на всей системе. Настройки JVM для Nexus 3 задаются не в systemd-юните напрямую, а в файле nexus.vmoptions рядом с бинарником:
# /opt/nexus/bin/nexus.vmoptions
-Xms1200M
-Xmx1200M
-XX:MaxDirectMemorySize=2G
Значения по умолчанию рассчитаны на сервер с приличным запасом RAM. Для продакшена с реальной нагрузкой Sonatype рекомендует от 4 ГБ RAM на сам процесс Nexus, и это не пустая перестраховка — при нескольких одновременных индексациях Maven-репозитория или синхронизации крупного Docker-прокси потребление памяти растёт быстро. Если сервер целиком укладывается в 2 ГБ, снижение -Xmx спасёт от падения по OOM, но не спасёт от медленной работы под нагрузкой — здесь правильный путь не «ужать до предела», а увеличить память сервера. После правки vmoptions обязательно перезапустите сервис:
systemctl restart nexus
journalctl -u nexus -f
Проверьте по логу, что процесс действительно поднялся и не упал повторно в первые секунды — так по свежим правкам heap сразу видно, хватило памяти или нет.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать сервер401/403 при публикации в Maven, npm, PyPI
Push или publish отваливается с 401 Unauthorized или 403 Forbidden, хотя логин и пароль вы вводите правильные. Здесь почти всегда дело не в самом пароле, а в правах доступа: в Nexus авторизация построена на связке «пользователь → роль → набор привилегий», и по умолчанию новый пользователь не имеет прав писать в конкретный репозиторий, даже если может в него читать.
Проверьте цепочку в Server Administration → Security → Roles и Privileges: у роли пользователя должна быть привилегия nx-repository-view-{format}-{repository}-add и -edit (или широкая nx-repository-view-*-*-* для админских ролей) на нужный репозиторий и формат. Для npm и Maven типичная ошибка — репозиторий подключён как hosted, но пользователь состоит только в роли с правами на proxy-репозитории.
Отдельная частая причина именно для Maven — не авторизация вовсе, а отсутствие креда в settings.xml у клиента:
<servers>
<server>
<id>nexus-releases</id>
<username>deployer</username>
<password>СильныйПароль</password>
</server>
</servers>
Значение id в settings.xml должно буква в букву совпадать с id репозитория в pom.xml в блоке distributionManagement — при малейшем расхождении Maven просто не подставит креды, и сервер честно вернёт 401. Для npm аналогичная ловушка — токен из npm login не прописался в .npmrc проекта, а лежит только в глобальном; проверьте это командой npm whoami --registry=https://nexus.example.com/repository/npm-hosted/.
Docker-репозиторий не пробрасывается через реверс-прокси
Docker-репозиторий в Nexus устроен иначе, чем Maven или npm: он требует отдельного HTTP/HTTPS-коннектора с собственным портом, потому что Docker-клиент не умеет ходить по вложенному пути /repository/.... Если вы просто открыли Docker-репозиторий как обычный путь за общим Nginx на 443, docker login и docker push будут падать с ошибками вида «404 page not found» или «unauthorized: authentication required» даже при верных правах.
Правильная схема — выделенный порт для конкретного Docker-репозитория в настройках репозитория (HTTP или HTTPS Connector, например 8082), и отдельный server-блок в Nginx именно под этот порт:
server {
listen 443 ssl;
server_name docker.example.com;
client_max_body_size 0;
location / {
proxy_pass http://127.0.0.1:8082;
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 https;
}
}
Ключевых момента два. Первый — client_max_body_size 0, иначе крупные слои образов будут обрываться на 413, как и в любом другом реверс-прокси перед реестром образов. Второй — домен Docker-репозитория должен резолвиться отдельно от основного домена Nexus (поддомен вроде docker.example.com), потому что Docker всегда обращается к порту 443 своего хоста и не умеет работать с путём в URL. Если общая логика реверс-прокси перед сервисами вам ещё не знакома, полезно заранее разобраться с типовыми граблями Nginx — они повторяются в любом сервисе за прокси, не только в Nexus.
Диск переполнен: blob-хранилища и cleanup policies
Nexus копит данные охотно и без напоминаний: каждый прокси-репозиторий кеширует всё, что через него когда-либо прошло, а хостируемые репозитории растут с каждым push. Через несколько месяцев активного использования /opt/sonatype-work/nexus3/blobs легко становится главным потребителем места на диске.
du -sh /opt/sonatype-work/nexus3/blobs/*
df -h
Первый шаг — не удалять файлы вручную (blob-хранилище Nexus имеет собственную структуру с метаданными, и ручное вмешательство его сломает), а настроить Cleanup Policies в Server Administration → Repository → Cleanup Policies. Задайте условия — например, удалять компоненты старше N дней или не скачивавшиеся дольше определённого срока — привяжите политику к репозиторию и запустите задачу очистки вручную или по расписанию через System → Tasks:
Task type: Cleanup repositories using their associated policy(ies)
Важный нюанс: применение cleanup policy помечает компоненты к удалению, но реальное освобождение места на диске в blob-хранилище происходит только после отдельной задачи Compact blob store — без неё старые данные логически удалены, но физически всё ещё занимают диск. Для прокси-репозиториев дополнительно проверьте Remove non-cataloged components — он чистит артефакты, которые больше не числятся в метаданных апстрима. Если место кончилось уже сейчас и разбираться с политиками некогда, экстренно освободить пару гигабайт можно через принудительный запуск Compact blob store на самом «тяжёлом» хранилище — но это разовая мера, а не замена регулярной чистки. Общие принципы того, что забивает диск на сервере и как с этим бороться системно, разобраны в статье про нехватку места на VPS.
Proxy-репозиторий не тянет пакеты у апстрима
Симптом: клиент запрашивает пакет через прокси-репозиторий Nexus (например, npm-proxy на registry.npmjs.org или Maven-proxy на Maven Central), а получает 404 или зависает надолго, хотя пакет точно существует. Причины здесь обычно сетевые, а не в самом Nexus.
Первое, что проверить — доступность апстрима напрямую с сервера:
curl -I https://registry.npmjs.org/express
Если сервер вообще не может достучаться до внешнего адреса (нет прямого доступа в интернет, нужен исходящий прокси), Nexus нужно явно настроить на использование HTTP-прокси в Server Administration → System → HTTP. Без этого прокси-репозиторий будет молча таймаутиться на каждом запросе. Вторая типичная причина — сертификат апстрима не в доверенном хранилище JVM, если у вас корпоративный или самоподписанный TLS где-то в цепочке; тогда в логе будет PKIX path building failed, и сертификат нужно добавить в keystore, которым пользуется Nexus.
Третья, менее очевидная причина — просто устаревший кеш метаданных. Nexus кеширует не только сами артефакты, но и ответы «not found» на определённое время, заданное в настройках прокси-репозитория (Negative Cache TTL). Если пакет только что появился в апстриме, а Nexus уже успел закешировать 404, повторный запрос вернёт тот же 404 до истечения TTL. Решение — вручную инвалидировать кеш через Invalidate cache в настройках репозитория, либо снизить Negative Cache TTL для быстро обновляющихся репозиториев.
Nexus не выдерживает нагрузку CI/CD и тормозит
Отдельная категория проблем — не ошибка, а деградация: Nexus поднимается и работает, но при параллельных запросах от CI-раннеров операции публикации становятся медленными, а иногда упираются в таймауты клиента. Чаще всего это тот же дефицит ресурсов, только не памяти, а диска и CPU: встроенная база Nexus и blob-хранилище активно пишут на диск, и на медленном сетевом или перегруженном диске это становится узким местом при нескольких параллельных пайплайнах.
Проверить, не диск ли тормозит систему, можно стандартными средствами мониторинга нагрузки на I/O, а если Nexus обслуживает несколько CI-раннеров одновременно — закладывать ресурсы стоит с запасом заранее, а не по факту первых жалоб команды. Если у вас уже настроен GitLab CI Runner или Jenkins рядом с Nexus на одном сервере, конкуренция за диск и память между ними — частый источник именно таких симптомов; при росте нагрузки логичнее развести артефактный сервер и раннеры CI по разным машинам, чем выжимать больше из одной. Практика настройки самого раннера и его типовые проблемы разобраны в статье про GitLab CI Runner на сервере — многие узкие места там пересекаются с Nexus, потому что оба сервиса активно пишут на диск при каждой сборке.
Если после чистки, cleanup policies и корректного heap Nexus всё ещё задыхается под нагрузкой команды, вопрос обычно не в настройках, а в самом сервере: артефактный менеджер любит одновременно быстрый диск, приличный объём RAM под JVM и стабильный канал наружу для проксирования апстримов. У MAATRIX можно арендовать VPS с NVMe-диском и нужным объёмом памяти под такие задачи в локациях RU, US и UK, с оплатой из России картой или криптой.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Сколько RAM нужно под Nexus Repository?
Минимум для тестового стенда — 2 ГБ, но для рабочей нагрузки с несколькими репозиториями и CI Sonatype рекомендует от 4 ГБ, иначе будут регулярные OutOfMemoryError под нагрузкой.
Почему после cleanup policy место на диске не освободилось?
Политика только помечает компоненты к удалению; физически blob-хранилище освобождается лишь после отдельной задачи Compact blob store.
Можно ли держать Docker- и Maven-репозитории на одном порту?
Нет, Docker-репозиторий требует отдельного HTTP/HTTPS-коннектора и, как правило, отдельного поддомена — Docker-клиент не умеет работать с вложенным путём в URL.
Почему прокси-репозиторий отдаёт 404 на пакет, который точно есть в апстриме?
Часто это устаревший негативный кеш (Negative Cache TTL); инвалидируйте кеш вручную в настройках репозитория или уменьшите TTL.
Где хранятся данные Nexus и что нужно бэкапить?
Все рабочие данные — база, blob-хранилища, конфигурация — лежат в /opt/sonatype-work/nexus3; именно эту директорию (а не каталог с дистрибутивом) нужно включать в резервное копирование.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →