При разработке программного обеспечения разработчики оперируют таким понятием как «артефакт». Артефакт представляет собой элемент (часть) разрабатываемого программного продукта. К артефактам относятся исполняемые и бинарные файлы, пакеты программ и т.д.
С расширением архитектуры и функционала разрабатываемого продукта количество артефактов начинает неуклонно расти. Появляется потребность в хранение большого количества артефактов. Для решения данной проблемы существует специальный класс программ — менеджеры репозиториев, которые позволяют эффективно хранить и управлять артефактами.
Одним из таких решений является продукт от американской компании Sonatype под названием Nexus Repository. Nexus поддерживает более 15 различных форматов артефактов среди которых можно выделить APT, Docker, Go, Helm, Maven, npm, PyPi и другие. С полным списком поддерживаемых артефактов можно ознакомиться в документации Nexus.
Существует 2 версии Nexus Repository: бесплатная и коммерческая. Отличие коммерческой от бесплатной версии заключается в наличии клиентской поддержки, а также большего числа поддерживаемых артефактов.
В этой статье мы будем устанавливать бесплатную версию.
cloud
На официальном сайте Sonatype также приведены примеры системных требований для определенного количества репозиториев и хранящихся в них артефактов.
1. Первым делом установим Java. Для этого сначала обновляем списки пакетов:
sudo apt update
2. Далее переходим к установке Java 8 версии, используя пакет OpenJDK:
sudo apt -y install openjdk-8-jre-headless
После установки проверяем, что Java установилась корректно, используя команду для вывода версии Java:
java -version
Если у вас установлено несколько версий Java, то необходимо переключиться на 8 версию. На сервере возможно присутствие двух и более версий Java, но использовать можно только одну. Для того чтобы переключиться на 8 версию Java, необходимо выполнить команду:
sudo update-alternatives --config java
В открывшемся интерактивном меню необходимо выбрать нужную версию Java при помощи клавиши TAB, далее подтвердить выбор, нажав Enter.
Следующие шаги относятся непосредственно к установке самого Nexus. Установка будет произведена в директорию /opt
.
3. Скачиваем архив с программой из официального сайта при помощи утилиты wget
:
sudo wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz
4. Разархивируем скачанный архив в директорию /opt
:
sudo tar -zxvf latest-unix.tar.gz -C /opt
5. На выходе будет создано 2 директории: sonatype-work
и nexus-3.61.0-02
, где 3.61.0-02
— это текущая версия Nexus. Архив с именем latest-unix
всегда содержит последнюю актуальную версию. Со временем версия будет изменяться. В директории sonatype-work
содержатся временные файлы, кэш-файлы и лог-файлы. Для удобства, изменяем название директории nexus-3.61.0-02
на nexus
:
sudo mv nexus-3.61.0-02/ nexus/
6. Для безопасной работы Nexus необходимо создать пользователя с именем nexus
:
sudo adduser nexus
Далее необходимо отключить возможность входа на сервер под этим пользователем. Для этого выполните команду:
usermod nexus -s
7. Назначаем владельца и группу для директорий /opt/nexus
и /opt/sonatype-work
, задав в качестве владельца ранее созданного пользователя nexus
:
sudo chown -R nexus:nexus nexus/ sonatype-work/
8. Открываем конфигурационный файл nexus.rc
, который располагается в /opt/nexus/bin/
, при помощи любого текстового редактора.
sudo nano /opt/nexus/bin/nexus.rc
Удаляем символ #
(символ комментария) и указываем пользователя с именем nexus
.
Сохраняем файл и выходим из него.
9. Чтобы запускать, останавливать и перезапускать Nexus, необходимо создать systemd
unit-файл. Создаем файл с именем nexus.service
:
sudo nano /etc/systemd/system/nexus.service
Со следующим содержимым:
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/opt/nexus/bin/nexus start
ExecStop=/opt/nexus/bin/nexus stop
User=nexus
Restart=on-abort
[Install]
WantedBy=multi-user.target
Сохраняем файл и выходим из него.
10. Запускаем nexus
:
sudo systemctl start nexus
И проверяем его статус:
systemctl status nexus
Если в статусе отображается active
, значит, Nexus успешно запущен.
11. Далее добавляем Nexus в автозагрузку:
sudo systemctl enable nexus
Полный запуск Nexus занимает в среднем 2-3 минуты. Готовность программы можно проверить в файле nexus.log
:
tail -f /opt/sonatype-work/nexus3/log/nexus.log
Найдя строку:
Started Sonatype Nexus OSS
По умолчанию веб интерфейс Nexus доступен с любых IP-адресов (0.0.0.0
) и слушает порт 8081
:
Главное меню веб-интерфейса Nexus:
При первом входе в веб-интерфейс Nexus нам предложат настроить несколько параметров. Для авторизации необходимо нажать на кнопку «Sign in», которая находится справа сверху.
По умолчанию в Nexus присутствует один пользователь с именем admin
, который обладает полномочиями администратора. При первом входе необходимо получить пароль:
Для этого на сервере, где установлен Nexus, необходимо выполнить команду:
cat /opt/sonatype-work/nexus3/admin.password
Полученный пароль используем для входа и нажимаем на кнопку «Sign in».
Далее необходимо произвести первичную настройку Nexus:
Придумываем новый пароль для пользователя admin:
Далее нам предложат включить или отключить анонимный доступ. При включенном анонимном доступе каждый пользователь, имеющий адрес репозитория, сможет искать, просматривать и скачивать артефакты без аутентификации. Если же анонимный доступ выключить, то для работы с репозиториями потребуется аутентификация при помощи логина и пароля:
На последнем шаге программа уведомляет, что настройка успешно выполнена и можно начать использовать Nexus Repository:
Для того чтобы создать репозиторий для Docker-образов, необходимо перейти в веб-интерфейс Nexus и авторизоваться под учетной записью администратора.
Далее в главном меню нажать на кнопку Server administration and configuration (значок шестеренки):
В левом меню выбрать пункт Repositories:
Далее нажать на кнопку Create repository:
Выбрать из списка репозиторий с именем docker (hosted):
Nexus поддерживает 3 различных типа репозиториев:
Придумываем имя для репозитория, например docker-images
. Напротив параметра HTTP ставим чекбокс и задаем любой порт, который не занят на сервере, где установлен Nexus, например, 8083:
Для взаимодействия с репозиториями Docker Nexus использует коннекторы (connectors), которые позволяют задать порт, тем самым открывая доступ к репозиторию по протоколу HTTP или HTTPS. Однако по умолчанию Nexus доступен только по протоколу HTTP. Если попытаться выполнить команду docker login
на хосте, указав адрес реестра и порт репозитория и используя при этом протокол HTTP, то Docker отобразит ошибку http: server gave HTTP response to HTTPS client
.
По умолчанию Docker не поддерживает работу с репозиториями, которые используют самоподписанные сертификаты, а также репозитории по протоколу HTTP. Для того чтобы разрешить работу с репозиториями по протоколу HTTP, необходимо создать (если отсутствует) файл daemon.json
, который располагается в /etc/docker/
.
sudo nano /etc/docker/daemon.json
И прописать следующий блок:
{
"insecure-registries" : ["91.100.100.1000:8083"]
}
Где 91.100.100.1000:8083
— адрес, на котором располагается Nexus, и HTTP порт от репозитория Docker, который был задан ранее в веб-интерфейсе.
Сохраняем файл и выходим из него.
После этого необходимо перезапустить демон Docker:
sudo systemctl restart docker
Будьте внимательны, так как перезапуск агента Docker затронет работающие контейнеры. Часть из них не будет запущена автоматически, при условии, что контейнер не был ранее запущен с опцией --restart=always
.
Далее выполняем команду docker login
, указав в качестве адреса репозитория адрес, на котором находится Nexus, и порт от репозитория:
docker login 91.100.100.1000:8083
В качестве логина можно воспользоваться учетной записью администратора — admin
.
Проверим, сможем ли мы сделать push
(отправить образ в репозиторий). Для этого возьмем образ с alpine
:
Присвоим образу тег. Формат тега для Docker образов имеет следующий вид:
образ:тег адрес реестра:порт репозитория/имя_образа
docker tag alpine:latest 91.100.100.1000:8083/alpine-test
Проверяем, что у нас появился новый образ:
Для того чтобы выполнить push
в репозиторий, воспользуемся командой:
docker push 91.100.100.1000:8083/alpine-test
Переходим в веб-интерфейс Nexus, далее в созданный ранее репозиторий и видим, что образ успешно появился:
Правильным решением при работе с репозиториями Docker является использование протокола HTTPS. Для настройки HTTPS в Nexus выполняем следующие шаги:
1. Переходим в директорию /opt/nexus/etc/ssl
:
cd /opt/nexus/etc/ssl
2) Для генерации самоподписанного сертификата воспользуемся утилитой keytool
.
keytool
представляет собой утилиту командной строки для создания ключей и сертификатов. Также является хранилищем ключей для Java. Воспользуемся следующей командой для создания сертификата:
sudo keytool -genkeypair -keystore keystore.jks -storepass test12345 -keypass test12345 -alias jetty -keyalg RSA -keysize 2048 -validity 1000 -dname "CN=*.${NEXUS_DOMAIN}, OU=test, O=test1, L=Unspecified, ST=Unspecified, C=RU" -ext "SAN=DNS:nexus-repo.com,IP:91.10.10.00" -ext "BC=ca:true"
Значения, выделенные красным цветом, необходимо заменить на свои:
-keystore keystore.jks
— имя файла, в котором будет сохранен ключ. Используется формат .jks
;-storepass test12345
— задается пароль для доступа к хранилищу ключей;-keypass test12345
— задается пароль для доступа к закрытому ключу;-ext "SAN=DNS:nexus-repo.com,IP:91.10.10.00"
— задается доменное имя и IP-адрес сервера, на котором находится Nexus.Если в качестве доменного имени будет использоваться локальный домен, то его необходимо прописать в файле /etc/hosts
(для Linux) и C:\Windows\System32\drivers\etc\hosts
в Windows.
3. Далее извлекаем сертификат сервера из созданного файла с именем keystore.jks
при помощи команды:
sudo keytool -export -alias jetty -keystore keystore.jks -rfc -file nexus.cert
nexus.cert
— имя файла с сертификатом, которое будет получено на выходе.
4. Далее переходим к редактированию конфигурационного файла nexus-default.properties
, который находится в /opt/nexus/etc
:
sudo nano /opt/nexus/etc/nexus-default.properties
Находим блок, содержащий строку с комментарием # Jetty section
, и прописываем следующий параметр:
application-port-ssl=8443
Так мы задаем порт, на котором будет доступен HTTPS.
В этом же блоке прописываем следующую строчку с параметром:
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-https.xml,${jetty.etc}/jetty-requestlog.xml
5. Далее редактируем файл jetty-https.xml
, который находится в /opt/nexus/etc/jetty
:
sudo nano /opt/nexus/etc/jetty/jetty-https.xml
Находим блок с именем sslContextFactory
.
В строках KeyStorePassword
, KeyManagerPassword
, TrustStorePassword
прописываем пароль, который был задан на этапе генерации сертификата. В нашем примере пароль — test12345
.
Также в параметрах KeyStorePath
и TrustStorePath
можно задать имя сгенерированного сертификата:
6. После внесения всех изменений перезапускаем сервис nexus
:
sudo systemctl restart nexus
В ОС Linux сертификат должен быть установлен на уровне ОС, иначе при попытке авторизоваться в репозитории при помощи команды docker login
появится ошибка:
x509: certificate signed by unknown authority
Для установки сертификата в системах Ubuntu/Debian выполняем следующие шаги:
1. Устанавливаем пакет ca-certificates
:
sudo apt -y install ca-certificates
2. Установить сертификат можно только в формате .crt Другие форматы не поддерживаются. Так как на выходе файл сертификата был с расширением .cert
, необходимо изменить расширение на .crt
.
Для этого выполняем команду:
sudo mv nexus.cert nexus.crt
Копируем сертификат в директорию /usr/local/share/ca-certificates
:
sudo cp nexus.crt /usr/local/share/ca-certificates
3. Установка сертификата выполняется при помощи команды:
sudo update-ca-certificates
Для того чтобы настроить HTTPS в репозитории, необходимо перейти в веб-интерфейс Nexus, авторизоваться под учетной записью администратора. Далее в главном меню нажать на кнопку Server administration and configuration (значок шестеренки). В левом меню выбрать пункт Repositories, далее найти необходимый репозиторий. Напротив параметра HTTPS ставим чекбокс и задаем любой порт, который не занят на сервере, где установлен Nexus, например 8344:
Сохраняем изменения. На сервере выполняем команду docker login
, указав в качестве адреса репозитория адрес, на котором находится Nexus, и порт HTTPS от репозитория:
docker login nexus-repo.com:8344
В качестве логина можно воспользоваться учетной записью администратора — admin
.
Проверим, сможем ли мы сделать push
(отправить образ в репозиторий). Для этого возьмем образ с nginx
:
Присвоим образу тег. Формат тега для Docker образов имеет следующий вид:
образ:тег адрес реестра:порт репозитория/имя_образа
docker tag nginx:latest nexus-repo.com:8344/nginx-test
Проверяем, что у нас появился новый образ:
Для того чтобы выполнить push
в репозиторий, воспользуемся командой:
docker push nexus-repo.com:8344/nginx-test
Переходим в веб-интерфейс Nexus, далее в созданный ранее репозиторий и видим, что образ успешно появился:
Разверните Nexus Repository на серверах Timeweb Cloud
Nexus Repository является отличным решением для хранения и управления артефактами. Благодаря поддержке большого количества различных форматов артефактов данный продукт подойдет как небольшим командам разработки, так и более крупным.
Лучше через docker compose сделать, чтобы и lets encrypt был, и нексус, и система не засиралась
Грубое введение в заблуждение:
>Также для пользователя nexus необходимо отключить вход по паролю. Открываем файл sudoers при помощи команды:
sudo visudo
>Находим строку с комментарием # User privilege specification и добавляем следующую запись:
nexus ALL=(ALL) NOPASSWD: ALL
Это не отключение "входа по паролю",это разрешение пользователю nexus выполнять любые команды c sudo без пароля. Это крайне небезопасно.
Добрый день! Спасибо за замечание 💙 Мы убрали этот блок из инструкции.
Коварный писатель не сказал, что докер не любит самоподписанные сертификаты, и надо в настройках докера на клиенте добавить хост нексуса с новым портом в insecure-registries. Ну и добавлять юзера nexus в систему надо без права локального входа. А так спасибо за статью!
Добрый день! Очень рады, что статья пригодилась 😊 Момент про insecure-registries в статье есть — в разделе «Создание репозитория для хранения Docker-образов» :)
Параметр insecure-registries необходимо прописывать только тогда, когда используется адрес репозитория с HTTP. При использовании HTTPS достаточно только установить сертификат (его установку мы тоже рассмотрели в статье).
sudo tar -zxvf latest-unix.tar.gz -С /opt
-C флаг на русском
Спасибо, поправили 💙