Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI

О нас

Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI

Мы команда "Просоюз". В рамках учебного проекта мы сделали web приложения для профсоюза Сбербанка - https://prosouze.ru. Эта наша первая техническая статья, в которой мы хотим поделиться тем, как настроили процесс CI для нашего приложения

Немного об ОС

В качестве целевой ОС будем использовать debian 11 версии. Вы может использовать любую удобную вам систему.

Для debian выполним предварительные установки. Нам понадобиться docker, docker compose и git.

Как установить на docker тут

Как установить docker compose тут

Договор об именовании

В процессе работы мы будем оперировать следующими терминами:

  • IP_ADDRESS - публичный IP адрес сервера
  • IP_JENKINS - IP адресс сервера, на котором находиться jenkins
  • IP_NEXUS - IP адресс сервера, на котором находиться nexus
  • DOMAIN_NAME_NEXUS - доменное имя сервера, на котором хоститься nexus
  • DOMAIN_NAME_JENKINS - доменное имя серера, на котором хоститься jenkins

Установка и настройка Jenkins

Установка

Здесь находиться официальная документация по установки Jenkins на вашу ОС. Внимание, установите сначала java 17 версии, а уже потом выполните установку Jenkins.

Как только установка будет выполнена, убедитесь, что jenkins запущен: systemctl status jenkins.service.

Настройка прав доступа для Docker

Мы будем использовать docker (про установку docker здесь) для сборки образов нашего приложения, для этого, давайте дадим право пользователю jenkins пользоваться docker приложением.

$ id -nG jenkins $ usermod -aG docker jenkins $ id jenkins # Должен появиться docker

Теперь jenkins знает, что есть такой парень, как docker и готов с ним работать.

Проверяем

Уже сейчас jenkins готов к работе, переходе по порту 8080 и видим приветственное окно. Пароль при первом входе найдете, там не сложно. Откладываем jenkins и переходим к nexus.

Установка и настройка Nexus

Установка

Основная проблема, которая ждет нас при запуске nexus - отсутствие нормальной документации и разные версии java, так как nexus будет выполнять роль репозитория для хранения образов, развернем его в отдельном docker контейнере. Следующий docker-compose файл поможет вам увидеть web-версию nexus на :8081 порту.

Создаем volume для nexus

$ docker volume create --name nexus_data

Создаем docker-compose подобного вида. 8081 используется для Web версии, а 8083 для загрузки репозиториев. После запускаем `docker compose up -d`, чтобы запустить nexus в фоновом режиме. За репозитории переживать не стоит. Даже если nexus упадет, они находятся по пути: `/var/lib/docker/volumes/nexus_data/_data`

services: nexus: image: sonatype/nexus3 ports: - "8081:8081" - "8083:8083" volumes: - nexus_data:/nexus-data networks: - cicd_network volumes: nexus_data: external: true name: nexus_data networks: cicd_network: driver: bridge

Настройка Docker для работы с Nexus репозиторием

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

Начнем с того, что нам нужно сообщить docker, что появился прекрасный парень nexus.

  • Наш реестр для docker небезопасен. Прямо укажем docker-у, что мы доверяем нашему репозиторию
$ nano /etc/docker/daemon.json { "insecure-registries":["<IP_NEXUS>:8083"] }
  • Мы указали, что реестр безопасен, давайте скажем докеру, а где собственно находятся наши настройки
$ nano /etc/default/docker DOCKER_OPTS="--config-file=/etc/docker/daemon.json"
  • Как мы помним у docker-а единый демон (привет podman). Перезапустим наш docker-deamon
$ sudo systemctl restart docker

Настройка Nexus через web-интерфейс

Теперь про Nexus, он установлен, но он не готов принимать образы контейнеров, давайте подготовим его морально.

Переходим по ссылке :8081

Нас встречает окно авторизации, пароль, как всегда спрятан в файле по пути cat /var/lib/docker/volumes/nexus_data/_data/admin.password

Заходим по логином admin и паролям, nexus сразу предложит поменять пароль, от этого шага не отказываемся. Далее нас просят про анонимность, естественно, запрещаем копировать наши образы левым парням и девчонкам.

Создадим пользователя jenkins_build_image, это и будет наше jenkins приложение, которое будет собирать и отправлять приложения в репозиторий nexus. Внимание, указываем роль nx-admin, так как нам важно, чтобы пользователь мог добавлять новые образы. Новых пользователей создаем через Настройки -> Security -> Users -> Create local user.

Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI

Теперь необходимо создать репозиторий, куда будет отправляться наше приложение. Делается это через Create Repository.

Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI

Так как мы используем docker для сборки репозиториев, выбираем docker-репозиторий. Вопрос, их там 3, какой выбрать?

  • group -
  • hosted - если мы хотим хранить образы на хосте приложения
  • proxy - передать образ стороннему репозиторию

Указываем порт и выбираем протокол, в нашем случаи http протокол и 8083 порт.

Несмотря на то, что мы создали репозиторий, указали docker на какой порт будут приходить образы и по какому протоколу, нам все еще недоступен процесс аутентификации, для того, чтобы это исправить, зайдем в Realm и переместим Docker Bearer Token Realm в правую колонку. Зачем это нужно? При регистрации docker login нам выдадут токен и по этому токену мы можем закидывать наши образы в nexus.

Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI

Все операции выполнены. Теперь мы можем протестировать работу приложения. Для этого выполним несложную операцию:

$ git clone https://github.com/X0re4ik/fast-api-base-project.git
  • Соберем контейнер
$ docker build -t test_docker_repository ./fast-api-base-project/src/ $ docker image ls | grep "test_docker_repository" # Проверяем, что контейнер собрался

PS нам особо не важно, что за образ, рабочий ли он вообще. Главное, что мы можем собрать его без ошибок.

  • Авторизовываемся в nexus через docker

Если видим сообщение Login Succeeded, значит, настройка прошла успешно и docker с nexus подружились.

$ docker login <IP_NEXUS>:8083 -u jenkins_build_image -p <NEXUS_USER_PASSWORD> # Плохой пример, так как видны пароли $ docker login <IP_NEXUS>:8083 -u jenkins_build_image --password-stdin < ./nexus_jenkins_user_password.txt # Хороший, пароли спрятаны
Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI
  • Отправляем контейнер в nexus
$ docker tag <imageId or imageName> <nexus-hostname>:<repository-port>/<image>:<tag> $ docker push <nexus-hostname>:<repository-port>/<image>:<tag>

В нашем случаи: docker push <NEXUS_IP>:8083/test_docker_repository:latest

$ docker tag test_docker_repository <NEXUS_IP>:8083/fast-api:00.00.01 $ docker push <NEXUS_IP>:8083/fast-api:00.00.01
Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI
  • Проверим, что образ загружен в nexus, узнаем, где он храниться у нас локально и попробуем выполнить pull

В web версии мы увидели наш образ:

Установка и настройка Nexus и Jenkins, или как мы настроили процесс CI

Пробуем выполнить docker pull:

$ docker pull <IP_NEXUS>:8083/fast-api:00.00.01

Переходим на HTTPS

В процессе разработки мы будем активно эксплуатировать 3 приложения:

  • Jenkins - :8080
  • Nexus GUI - :8081
  • Nexus Docker repository - :8083

Пример приведён для nginx в качестве proxy сервера. Сертификаты были получены при помощи letsencrypt и cerbot.

В данном блоке приведены конфигурационные файлы для каждого из приложений. В тексе буду указаны пояснения. Для jenkins есть хороший материал по настройки для nginx

HTTPS для JenkinsHTTPS для Jenkins

# /etc/nginx/sites-enabled/jenkins.conf upstream jenkins { keepalive 32; # keepalive connections server 127.0.0.1:8080; # jenkins ip and port } # Required for Jenkins websocket agents map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 5001 ssl; server_name gitlab-tester-test.ru; ssl_certificate /etc/letsencrypt/live/gitlab-tester-test.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/gitlab-tester-test.ru/privkey.pem; # this is the jenkins web root directory # (mentioned in the output of "systemctl cat jenkins") root /var/run/jenkins/war/; access_log /var/log/nginx/jenkins.access.log; error_log /var/log/nginx/jenkins.error.log; # pass through headers from Jenkins that Nginx considers invalid ignore_invalid_headers off; location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" { # rewrite all static files into requests to the root # E.g /static/12345678/css/something.css will become /css/something.css rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last; } location /userContent { # have nginx handle all the static requests to userContent folder # note : This is the $JENKINS_HOME dir root /var/lib/jenkins/; if (!-f $request_filename){ # this file does not exist, might be a directory or a /**view** url rewrite (.*) /$1 last; break; } sendfile on; } location / { sendfile off; proxy_pass http://jenkins; proxy_redirect default; proxy_http_version 1.1; # Required for Jenkins websocket agents proxy_set_header Connection $connection_upgrade; proxy_set_header Upgrade $http_upgrade; proxy_set_header Host $http_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; proxy_max_temp_file_size 0; #this is the maximum upload size client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_request_buffering off; # Required for HTTP CLI commands } }

HTTPS для Nexus GUI

# /etc/nginx/sites-enabled/nexus.conf upstream nexus { keepalive 32; server 127.0.0.1:8081; } server { listen 5002 ssl; server_name gitlab-tester-test.ru; ssl_certificate /etc/letsencrypt/live/gitlab-tester-test.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/gitlab-tester-test.ru/privkey.pem; access_log /var/log/nginx/nexus.access.log; error_log /var/log/nginx/nexus.error.log; ignore_invalid_headers off; location / { sendfile off; proxy_pass http://nexus; proxy_redirect default; proxy_http_version 1.1; } }

HTTPS для Nexus Docker Repository

# /etc/nginx/sites-enabled/nexus_docker_registry.conf upstream nexus_docker_registry { keepalive 32; # keepalive connections server 127.0.0.1:8083; # jenkins ip and port } server { listen 5003 ssl; server_name gitlab-tester-test.ru; ssl_certificate /etc/letsencrypt/live/gitlab-tester-test.ru/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/gitlab-tester-test.ru/privkey.pem; access_log /var/log/nginx/nexus_docker_registry.access.log; error_log /var/log/nginx/nexus_docker_registry.error.log; ignore_invalid_headers off; proxy_send_timeout 120; proxy_read_timeout 300; proxy_buffering off; keepalive_timeout 5 5; tcp_nodelay on; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; location / { proxy_pass http://nexus_docker_registry ; 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 "http"; } }
Начать дискуссию