Sonatype Nexus — программный продукт, который представляет собой менеджер репозиториев для хранения артефактов. Поддерживаются такие форматы артефактов, как Maven, образы Docker, Python PyPI, RubyGems, npm, nuget, deb и другие. С полным списком поддерживаемых артефактов можно ознакомиться в официальной документации.

По умолчанию установка происходит без включенного SSL. В данной статье будет описана установка Sonatype Nexus в контейнере Docker с использованием Nginx в качестве обратного прокси сервера, а также будет рассмотрено получение бесплатного доменного имени на сайте freenom.com и создание SSL-сертификата при помощи службы Let’s Encrypt.

Установка будет произведена на операционной системе Ubuntu 20.04.04 LTS.

Установка Nexus при помощи Docker

Первым делом нужно установить Docker. Для этого необходимо воспользоваться инструкцией с официального сайта Docker в разделе установки на ОС Ubuntu

После того как Docker будет установлен, надо создать директорию, где будут хранится данные Nexus:

mkdir nexus-data

Далее необходимо развернуть контейнер с nexus, пробросив порт 8081 наружу, и примонтировать ранее созданную директорию nexus-data:

docker run -d -p 8081:8081 --name nexus -v nexus-data:/nexus-data sonatype/nexus3

Разворачивание контейнера займёт несколько минут.

Статус развертывания можно проверить с помощью команды:

docker logs -f <ID контейнера>

Где <ID контейнера> — уникальный ID (номер) контейнера. Узнать его можно при помощи команды: 

docker ps

В данном случае ID контейнера — 1ce41c2632f6.

Контейнер будет запущен, когда в выводе команды docker logs появится строчка:

Started Sonatype Nexus OSS 3.38.1-01

После запуска Nexus будет доступен по адресу http://<ip_адрес_хоста>:8081

В данном примере IP-адреса хоста — 192.168.92.139. Перейдем по данному IP и порту 8081 в браузере, чтобы убедиться, что веб-интерфейс Nexus работает:

Чтобы войти из-под учётной записи администратора с именем admin, необходимо получить пароль. Пароль можно получить из контейнера, выполнив команду:

docker exec -it < ID контейнера> /bin/bash

Где вместо <ID контейнера> необходимо подставить ID контейнера с Nexus:

Далее внутри контейнера выполнить команду:

cat nexus-data/admin.password

Файл внутри контейнера admin.password будет удален сразу после первого входа.

В веб-интерфейсе Nexus нужно перейти в раздел Sign-in (находится справа сверху) и авторизоваться:

При первом входе Nexus сразу же сообщит, что стандартный пароль необходимо изменить:

На этом установка Nexus завершена.

Создание домена и сертификатов

Для создания домена для хоста, где установлен Nexus, можно воспользоваться одним из нескольких сервисов, которые выдают доменные имена. В качестве примера будет использован сервис под названием Freenom. Одним из его главных преимуществ является то, что он позволяет зарегистрировать бесплатный домен второго уровня в одной из следующих зон: .tk, .ml, .ga, .cf, .gq, который будет действовать один год бесплатно. Также из преимуществ Freenom можно выделить переадресацию URL, предоставление бесплатного DNS-сервиса.

Для получения бесплатного домена необходимо перейти на сайт Freenom и на главной странице ввести имя желаемого домена. В последнее время на сайте проявляется ошибка, которая заключается в том, что доменное имя необходимо вводить сразу вместе с зоной. 

Например, если нужен домен с именем my-nexus-repository, то в поле поиска необходимо ввести my-nexus-repository.tk. Вместо .tk можно использовать следующие доменные зоны: .ml, .ga, .cf, .gq. После этого потребуется нажать на кнопку «Проверить доступность»:

Если выбранное вами имя свободно, его можно получить бесплатно, нажав на зелёную кнопку «Оформить заказ»:

На следующем шаге нужно выбрать, в течение какого периода будет доступен выбранный вами домен. Бесплатно пользоваться доменом можно максимум 1 год с момента создания. Для выбора периода необходимо раскрыть меню Period и выбрать нужное значение:

После этого нажать на кнопку «Continue».

На следующем шаге потребуется войти в свой аккаунт. Если аккаунта у вас нет, то в поле слева необходимо ввести свой email для регистрации. На указанный адрес придёт письмо с подтверждением. После перехода по ссылке из письма понадобится заполнить контактные данные. Если вы уже зарегистрированы, то просто войдите в аккаунт:

Как только процесс создания домена будет завершен, войдите в личный кабинет — раздел Вход на главной странице сайта:

После авторизации необходимо перейти в меню Services, далее выбрать My Domains:

В открывшемся разделе будут находиться все ваши домены:

Следующий этап – добавление записей типа A и TXT. Для этого нажмите на Manage Domain справа от имени домена и в открывшемся окне перейдите в раздел Manage-Freenom DNS:

Необходимо добавить следующие записи:

A      3600 <внешний_IP_адрес_хоста_где_развернут_Nexus>
A      300 <внутренний_IP_адрес_хоста_где_развернут_Nexus>
WWW   A      300 <внутренний_IP_адрес_хоста_где_развернут_Nexus>
TXT 	3600 <внешний_IP_адрес_хоста_где_развернут_Nexus>

 Узнать внешний IP-адрес можно при помощи утилиты wget:

wget -O - -q icanhazip.com

В итоге должны быть созданы следующие DNS записи:

Чтобы сохранить, необходимо нажать на кнопку «Save Changes»

Установка certbot и let’s encrypt

 Следующий шаг – установка пакетов certbot и let’s encrypt.

Certbot — это ACME-клиент, который автоматически создаёт и устанавливает сертификаты, не требуя остановки или перезапуска web-сервера. Данный клиент рекомендует использовать сам let’s encrypt.

Для установки данных пакетов необходимо выполнить команду:

sudo apt -y install certbot letsencrypt

Далее нужно сгенерировать сертификаты для созданного домена. Для этого воспользуйтесь командой:

sudo certbot certonly --manual --agree-tos --email <email-address> --preferred-challenges=dns -d <имя_домена>

Где вместо <email-address> необходимо прописать свой адрес электронной почты, а вместо <имя_домена> — имя домена, который был зарегистрирован.

При появлении сообщения:

Would you be willing to share your email address with the Electronic Frontier

Foundation, a founding partner of the Let's Encrypt project and the non-profit

organization that develops Certbot? We'd like to send you email about our work

encrypting the web, EFF news, campaigns, and ways to support digital freedom.

в терминале нужно ввести N и нажать на Enter:

При появлении сообщения:

Please deploy a DNS TXT record under the name

_acme-challenge.my-nexus-repository.tk with the following value:

необходимо, не нажимая клавишу «Enter», вернуться в панель регистрации DNS записей freenom и создать TXT запись для домена:

_ACME-CHALLENGE TXT 3600 <значение_из_команды>

Вместо <значение_из_команды> требуется вписать значение, которое выведет программа:

DNS запись должна выглядеть следующим образом:

После сохранения изменений надо дождаться, когда запись будет зарегистрирована. Данный процесс может занять 10 минут и более. Проверить, зарегистрирована ли запись, можно с помощью команды:

dig _acme-challenge.my-nexus-repository.tk txt +short

Где вместо my-nexus-repository.tk необходимо вписать свой ранее созданный домен. После того как команда вернет ранее записанное значение из команды при генерации сертификатов, можно нажимать на клавишу «Enter».

В результате будут сгенерированы 4 файла c сертификатами, которые сохранятся в /etc/letsencrypt/live/<имя_домена>. В данном случае домен называется my-nexus-repository.tk, поэтому сертификаты находятся по пути /etc/letsencrypt/live/my-nexus-repository.tk:

Настройка Nginx в качестве reverse proxy

Следующий этап – настройка веб-сервера Nginx в качестве обратного прокси.

Обратный прокси-сервер – это компьютер (или сервер), который обрабатывает запросы из сети интернет и перенаправляет их на компьютер(ы) внутренней сети.

Nginx так же, как и Nexus, будет развернут в контейнере Docker.

Для начала создаем директорию, в которой будут хранится все файлы:

mkdir nginx && cd nginx

Далее в данную директорию необходимо скопировать ранее сгенерированные сертификаты. В моем случае сертификаты находятся в директории /etc/letsencrypt/live/my-nexus-repository.tk, поэтому в данном случае команда будет выглядеть следующим образом:

cp *.pem /home/alex/nginx/

Сразу после копирования сертификатов нужно выставить владельца и права на сами сертификаты. В качестве владельца будет задан текущий пользователь сессии, а права будут выставлены как 600 (только владелец файла может читать/записывать):

sudo chown USER *pem
chmod 600 *pem

Далее создаем и сохраняем Dockerfile со следующим содержимым:

FROM nginx
COPY ./nginx.conf /etc/nginx/nginx.conf

Также необходимо создать конфигурационный файл со следующими настройками для Nginx, который будет проброшен в контейнер:

nano nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
error_log /var/log/nginx/error.log warn;
access_log /dev/null;
proxy_intercept_errors off;
proxy_send_timeout 120;
proxy_read_timeout 300;
server {
listen 8080 default_server;
server_name my-nexus-repository.tk;
return 301 https://request_uri;
}
server {
listen 443 ssl;
server_name my-nexus-repository.tk;
Allow upload of large files,
needed if Nexus is going to host large size artifacts
client_max_body_size 20G;
Add the certificate and key generated earlier
ssl_certificate /etc/nginx/conf.d/cert.pem;
ssl_certificate_key /etc/nginx/conf.d/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
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"; proxy_pass http://172.17.0.2:8081;
}
location /v2/ {
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"; proxy_pass http://172.17.0.2:8082;
}
}
}

Здесь необходимо внести следующие правки.

Вместо my-nexus-repository.tk вписать свой ранее зарегистрированный домен (параметр server_name в директивы http и server).

В директиве server в параметре client_max_body_size можно задать необходимый максимально допустимый размер тела запроса клиента. В контексте использования Nexus это будет применимо, если хранимые артефакты занимают много места. В данном примере указано 20 ГБ. Это означает, что загрузить артефакт более 20 ГБ не получится и Nginx вернет ошибку 413 Request Entity Too Large.

В директивах location / и location /v2/ в параметре proxy_set_header X-Forwarded-Proto необходимо прописать IP-адрес контейнера с Nexus.

Для того чтобы узнать IP адрес контейнера, нужно выполнить команду:

docker inspect <ID_контейнера> | grep IP

Где вместо <ID_контейнера> требуется подставить ID контейнера с Nexus. Узнать ID контейнера можно при помощи команды docker ps:

IP-адрес будет находиться в параметре IPAddress.

После того как конфигурационный файл приведен к соответствующему виду, необходимо собрать образ контейнера Nginx, передав ему конфигурационный файл nginx:

docker build -t nginx-ssl .

Как только сборка контейнера будет завершена, можно запустить контейнер с Nginx с публикацией портов 8080 и 443:

docker run -d -p 8080:8080 -p 443:443 --name nginx -v $(pwd):/etc/nginx/conf.d 
--restart unless-stopped nginx-ssl

Дождаться, когда контейнер с Nginx перейдет в статус Up:

После этого в браузере необходимо перейти по адресу https://имя_вашего_домена. В данном случае имя домена — my-nexus-repository.tk:

Можно увидеть значок защищенного соединения:

и действительный сертификат:

Комментарии (3)


  1. AotD
    21.04.2022 12:02

    Сюда бы docker-compose, раз у вас 2 зависимых контейнера, а ещё б туда же certbot, а то ручками сертификат выдали, в папочку подложили, а через N месяцев он протух и снова всё ручками, да перезапуская контейнеры?


    1. 1shaman Автор
      22.04.2022 10:57

      Вы правы. В моем случае данный кейс использовался один раз, для долгосрочного использования необходим Docker Compose.


  1. hyperwolf
    22.04.2022 17:15

    Советую выставлять proxy_buffer off в nginx, иначе могут быть неожиданные обрывы скачивания крупных >1 гб артефактов.