Предположим вы из тех, кто когда-то давно поднял nexus в докер контейнере, поставил дополнительно плагин nexus-repository-composer, долго с этим nexus-ом жил, т.к. постоянно не хватало времени поставить в спринт задачу по его обновлению, да и что скрывать, работал до этого без особых проблем. Из многочисленных репозиториев в наличии у вас есть например пара реп с форматом хранения composer - один с типом hosted и один с типом proxy (https://packagist.org/). Описание проблемы пришло со стороны php разработчиков - обнаружили, что nexus proxy репозиторий для packagist отдает далеко не свежие версии пакетов, связано это с тем, что наш плагин nexus-repository-composer работает со старой версией протокола composer (V1), а это уже считается древним легаси (как мне объяснили пхп разработчики). Долго тянули с обновлением nexus, теперь пробуем разобраться как это всё обновить.
Некоторые ссылки, чтобы понять как обновлять nexus и плагин nexus-repository-composer для него:
* https://help.sonatype.com/en/orientdb-downloads.html
As of Nexus RepositoryTM release 3.71, H2 is the embedded database as support for OrientDB is deprecated
Nexus Repository Composer 0.1+ is only compatible with Nexus Repository Manager 3.71 or later.
Use 0.0.x for older NXRM installations.
* https://github.com/sonatype-nexus-community/nexus-repository-composer/tags
Плагин nexus-repository-composer до версии 0.0.29 включительно совместим с nexus до версии 3.70.X, при этом этот плагин будет работать только с composer v1 repository format.
* https://help.sonatype.com/en/ce-onboarding.html?#community-edition-limitations
Administrators of Nexus Repository deployments on versions 3.66.0 or above can view that instance's current
usage statistics (component count, requests per min/day) on their home screens after logging into the instance
https://community.sonatype.com/t/sonatype-nexus-repository-oss-requests-per-day-hard-limit/14555/5
You’re at version 3.76.x which is still the “old” OSS edition where these limits are just a recommendation.
However if you’d update to 3.77+, you’d be facing hard limits of 100000 components and 200000 requests per day.
See Community Edition Onboarding for more detailed description of how these limits work.
Т.е. нужно обновляться максимум пока до версии 3.76.X, если опасаетесь, что ваш инстанс nexus будет выходить за пределы указанных лимитов.
Какие шаги были сделаны:
0. Научиться собирать плагин nexus-repository-composer:
- https://github.com/sonatype-nexus-community/nexus-repository-composer/releases/tag/composer-parent-0.0.29 - качаем репо с определенным тегом, распаковываем - docker build -t nexus-repository-composer . - потом стартуем временный контейнер на базе образа nexus-repository-composer и забираем оттуда файл /opt/sonatype/nexus/deploy/nexus-repository-composer-0.0.29-bundle.kar
1. Собрал свой образ my-registry.test.ru/company/nexus-bundle:3.70.2-java11-alpine с плагином nexus-repository-composer версии 0.0.29, за пример можно взять такой Dockerfile:
ARG NEXUS_VERSION=3.70.2-java11-alpine FROM sonatype/nexus3:$NEXUS_VERSION #install COMPOSER repo ARG COMPOSER_VERSION=0.0.29 ARG COMPOSER_TARGET=/opt/sonatype/nexus/deploy/ COPY plugins/nexus-repository-composer-${COMPOSER_VERSION}-bundle.kar ${COMPOSER_TARGET}
2. Далее запускаюсь с этого образа на текущих данных nexus (напомню, он был запущен в контейнере и имеет версию 3.15.2). Примерная команда для запуска:
docker run -d -p 8081:8081 -v /home/nexus/data:/nexus-data --name nexus-test my-registry.test.ru/company/nexus-bundle:3.70.2-java11-alpine
Nexus сам прозрачно произведет нужные действия по миграции (обновлению) с версии 3.15.2 на 3.70.2. По сути ничего не меняется - плагин composer всё тот же старенький, просто обновилась версия nexus. Как минимум, используемая ниже утилита nexus-db-migrator-3.70.1-03.jar вряд ли будет работать с такой старой версией nexus, поэтому промежуточно обновлять nexus всё равно нужно.
3. Делаем бэкап composer пакетов. В моем случае я бэкаплю только репозиторий типом hosted (т.е. только что сами разработчики собирали), бэкапить многочисленные пакеты с packagist нет большого смысла (они потом все равно подтянутся при выполнении composer install). У нас репо так и называется - composer
cat composer_backup.sh #!/bin/bash -e NXRM="https://nexus.test.ru" REPO="composer" FILEEXT="composer" FILENAME="${REPO}.list" TOKEN="" get_token(){ TOKEN="" TMPTOKEN="" TMPTOKEN=$(tail ${FILENAME} | grep "continuationToken") TOKEN="$(echo $TMPTOKEN | awk '{print $3}' | awk -F\" '{print $2}')" if [[ "$TOKEN" = "" ]]; then return; fi TOKENFULL="continuationToken=${TOKEN}&" echo $TOKEN } > ${FILENAME} while : ; do curl -X 'GET' \ "${NXRM}/service/rest/v1/assets?${TOKENFULL}repository=${REPO}" \ -H 'accept: application/json' >> ${FILENAME} get_token if [[ "$TOKEN" = "" ]]; then break; fi done grep -n "downloadUrl" ${REPO}.list | grep ${FILEEXT} | awk '{print $4}' | awk -F\" '{print $2}' > ${REPO}.urls mkdir -p ${REPO} cd ${REPO} while read -r URL; do curl -LO -C - "${URL}" done<../${REPO}.urls
Скрипт взят с https://debuntu.ru/n/download-all-assets-from-nexus-repository-using-curl/. В нашем случае загрузка заняла где-то 20 мин, если бы выгружались пакеты и из packagist proxy, то было бы значительно дооольше. Создалась папка composer, в ней многочисленные файлы с расширением zip и некоторое кол-во файлов с json расширением.
4. В GUI удаляем все composer репозитории (с типом proxy и hosted), т.к. их не сможем мигрировать на H2 database => они будут занимать место на диске.
5. Копируем в контейнер "мигратор" (https://help.sonatype.com/en/download.html#nexus-repositorytm-database-migrator), выполняем команды внутри контейнера:
# docker cp nexus-db-migrator-3.70.1-03.jar nexus-test:/opt/sonatype/sonatype-work/nexus3/backup/ # docker exec -it nexus-test sh $ /opt/sonatype $ cd sonatype-work/nexus3/backup/
В GUI выбираем Task backup-database, в результате в каталоге backup появятся бэкапы (напомню - текущий инстанс nexus хранит свои данные в orientdb). У меня это такие файлы:
accesslog-2025-06-13-01-30-00-3.15.2-01.bak audit-2025-06-13-01-30-00-3.15.2-01.bak component-2025-06-13-01-30-00-3.15.2-01.bak config-2025-06-13-01-30-00-3.15.2-01.bak security-2025-06-13-01-30-00-3.15.2-01.bak
Шаг с бэкапом обязателен, этого требует утилита миграции.
6. Далее внутри контейнера:
$ /opt/sonatype/nexus/bin/nexus stop $ /opt/sonatype/sonatype-work/nexus3/backup $ java -Xmx2G -Xms2G -XX:+UseG1GC -XX:MaxDirectMemorySize=28672M -jar nexus-db-migrator-3.70.1-03.jar --migration_type=h2 ... 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - Migration job finished at Tue May 27 07:33:20 GMT 2025 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - Migration job took 30 seconds to execute 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - 93911 records were processed 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - 18870 records were filtered 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - 0 records were skipped 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - 75041 records were migrated 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - Created 'Rebuild repository browse' and 'Rebuild repository search' tasks. They will automatically one-time run after starting your Nexus Repository instance. 07:33:20 [main] INFO c.s.n.d.m.l.ProvidingJobInfoListener - Migrated the following formats: [APT, COCOAPODS, CONAN, CONDA, DOCKER, GITLFS, GO, HELM, MAVEN2, NPM, NUGET, P2, PYPI, R, RAW, RUBYGEMS, YUM
7. Действия после миграции:
/opt/sonatype/sonatype-work/nexus3/backup $ mv nexus.mv.db ../db/ /opt/sonatype/sonatype-work/nexus3/backup $ echo "nexus.datastore.enabled=true" >> /opt/sonatype/sonatype-work/nexus3/etc/nexus.properties
По-правильному, nexus.datastore.enabled=true надо делать на уровне сборки Dockerfile или пробрасывать конфиг извне при запуске контейнера, здесь я привел чисто для простоты понимания.
Также надо будет удалить старые данные от orientdb (команды запускаются извне, на хостовой машине):
server ~ # rm -rf /home/nexus/data/db/analytics server ~ # rm -rf /home/nexus/data/db/component server ~ # rm -rf /home/nexus/data/db/config server ~ # rm -rf /home/nexus/data/db/frozen.marker server~ # rm -rf /home/nexus/data/db/model.properties server ~ # rm -rf /home/nexus/data/db/OSystem server ~ # rm -rf /home/nexus/data/db/security/ server ~ # ls -l /home/nexus/data/db/ total 254252 -rw-r--r-- 1 200 200 260349952 May 29 09:28 nexus.mv.db
Удаление старых данных не мешает работе nexus-а, но внутри контейнера будет писать:
INFO [FelixStartLevel] *SYSTEM org.sonatype.nexus.datastore.DataStoreConfigurationDefaultSource - Loaded 'nexus' data store configuration defaults (Embedded H2) WARN [FelixStartLevel] *SYSTEM org.sonatype.nexus.datastore.mybatis.MyBatisDataStore - Database directory contains unsupported legacy database files; remove legacy files as soon as possible.
8. Стопаем контейнер и запускаемся на более новом образе nexus. Предварительно аналогично собрал плагин nexus-repository-composer-0.1.9-bundle.kar и положил в свой регистри my-registry.test.ru/company/nexus-bundle:3.71.0-java17-ubi (см шаг 1)
docker run -d -p 8081:8081 -v /home/nexus/data:/nexus-data --name nexus-new my-registry.test.ru/company/nexus-bundle:3.71.0-java17-ubi
9. Создаем в GUI обратно 2 репозитория composer с типами proxy (например с именем packagist) и hosted (например с именем composer). В composer hosted repo загружаем ранее сделанный бэкап:
cat composer_restore.sh NXRM="https://nexus.test.ru" USERPASS="admin:XXX" REPO="composer" cd composer for file in *.zip do #echo $file vendor=`echo $file | sed 's/\([a-z]*\)-\([.a-z0-9_-]*\)-\([0-9.]*\)\.zip/\1/'` project=`echo $file | sed 's/\([a-z]*\)-\([.a-z0-9_-]*\)-\([0-9.]*\)\.zip/\2/'` version=`echo $file | sed 's/\([a-z]*\)-\([.a-z0-9_-]*\)-\([0-9.]*\)\.zip/\3/'` echo $vendor-$project-$version.zip curl -u${USERPASS} --fail --show-error --upload-file $vendor-$project-$version.zip "https://nexus.test.ru/repository/composer/packages/upload/$vendor/$project/$version" done
В итоге запущен инстанс nexus версии 3.71.0-java17-ubi с плагином nexus-repository-composer-0.1.9-bundle.kar внутри, данный плагин уже нормально работает с composer V2 repository format. Собранные composer пакеты также перенесены в ново созданный репозиторий. Само собой, прежде чем делать все манипуляции, стоит потренироваться и всегда предварительно делать бэкапы. Далее с версии 3.71.0-java17-ubi уже не должно быть больших сложностей перейти на версию 3.76.X, также при желании далее перенести backend хранения с H2 на Postgresql.