Устанавливаем Jenkins на облачный сервер для автоматизации сборки приложений

Устанавливаем Jenkins на облачный сервер для автоматизации сборки приложений - 1

Привет, Хабр! Меня зовут Завур, я фронтенд-разработчик в Selectel.

Сборка, тестирование и развертывание приложения — операции, которые приходится повторять при каждом изменении кодовой базы. С ростом проекта ручная сборка и деплой начинают отнимать время и приводят к ошибкам. Эту рутину убирает практика непрерывной интеграции и доставки (CI/CD) — конвейер, который автоматически запускает тесты, собирает артефакты и публикует приложение при каждом изменении репозитория.

Многие команды используют для этого встроенные инструменты хостинга кода — GitLab CI или GitHub Actions. Но если нужен независимый сервер автоматизации, который не привязан к конкретной платформе, подойдет Jenkins. Это open-source инструмент с почти двадцатилетней историей, большой экосистемой плагинов и поддержкой практически любых технологий. Он может собирать проекты из любого Git-репозитория, запускать тесты, собирать Docker-образы и разворачивать приложения, а ограничение на количество сборок определяется только ресурсами сервера.

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

Что такое Jenkins

Проект появился в 2004 году под названием Hudson, но после конфликта с Oracle сообщество в 2011 году переименовало его в Jenkins и с тех пор развивается уже под новым именем.

Jenkins построен по архитектуре «контроллер + агенты». Контроллер — центральный сервер: он хранит настройки, ведет очередь задач и отвечает за веб-интерфейс. Сами сборки выполняют агенты — отдельные рабочие машины. На старте контроллер может выполнять сборки сам, и для небольших проектов этого достаточно. Когда нагрузка растет, к нему подключают дополнительных агентов — например, еще один виртуальный сервер. Так производительность конвейера можно наращивать, не трогая сам Jenkins.

Задачи описываются пайплайнами — последовательностями шагов в файле Jenkinsfile в корне репозитория: получение кода из git, сборка, тесты, публикация артефактов. Конвейер хранится вместе с проектом и проходит через код-ревью, как обычный код.

А теперь разберемся, какие ресурсы нужны Jenkins и какой сервер выбрать под нашу задачу.

Требования к ресурсам

По официальной документации, минимум для запуска Jenkins — 256 МБ оперативной памяти и 1 ГБ на диске. На практике ресурсов уходит куда больше, и зависит итоговый объем не от самого Jenkins, а от нагрузки.

Легкой нагрузкой считаются линтеры, unit-тесты, сборка небольших проектов при 10–20 коммитах в день. Для таких задач хватит минимальной конфигурации: 2 vCPU и 2–4 ГБ RAM. Это отличный вариант для небольших команд и пет-проектов: вы можете развернуть облачный сервер в Selectel за пару минут, а если понадобится больше мощности, то конфигурацию можно увеличить в любой момент.

Когда же мы говорим о тяжелой нагрузке, речь идет о компиляции больших C++/Go-проектов, мобильных сборках и запуске нескольких параллельных пайплайнов. В этом случае конфигурацию нужно будет выбрать мощнее, иначе пайплайны будут висеть в очереди, а сборки падать с ошибками нехватки памяти, когда ядро начнет завершать процессы.

Если ресурсов не хватает, есть три пути:

  • Увеличить мощности облачного сервера. Добавить vCPU и RAM в панели управления.

  • Вынести сборки на агентов. Контроллер останется на небольшом сервере для работы веб-интерфейса и очереди задач, а тяжелую нагрузку возьмут на себя отдельные машины — контейнеры или другие облачные серверы.

  • Перейти на выделенный сервер. Это решение подходит для больших команд с большим объемом артефактов, хранением истории сборок и высокими требованиями к дисковой подсистеме.

В рамках статьи выберем сбалансированный вариант для старта: 2 vCPU, 4 ГБ RAM и 50 ГБ SSD. Этого с запасом хватит для контроллера и небольших сборок на нем.

Устанавливаем Jenkins на облачный сервер для автоматизации сборки приложений - 2

Облачная инфраструктура для ваших проектов

Виртуальные машины в Москве, Санкт‑Петербурге и Новосибирске с оплатой по потреблению.

Подробнее →

Заказываем облачный сервер

Для начала войдем в панель управления Selectel и пройдем следующий маршрут: Продукты → Вычисления → Облачные серверы.

Разделы панели управления.

Разделы панели управления.

На открывшейся странице нажимаем Создать сервер.

Раздел «Выделенные серверы».

Раздел «Выделенные серверы».

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

В качестве операционной системы выберем Ubuntu 24.04 LTS: она имеет долгосрочную поддержку, оснащена привычным пакетным менеджером apt и поддерживает официальные пакеты Jenkins. Все приведенные далее в инструкции команды рассчитаны именно на эту версию Ubuntu, и хотя процесс установки на Debian будет аналогичен, для Windows потребуется совершенно другой сценарий — его мы сегодня затрагивать не будем.

При выборе региона и пула ориентируйтесь на географическое расположение вашей команды. Для одиночного инстанса Jenkins этот параметр не играет ключевой роли, однако при добавлении сторонних агентов в будущем их лучше размещать в том же пуле.

На этапе выбора конфигурации задайте ресурсы, рассчитанные ранее. В нашем случае это два ядра vCPU, 4 ГБ оперативной памяти и SSD-диск объемом 50 ГБ.

Далее в мастере создания добавьте SSH-ключ и нажмите Создать сервер. Если ключа еще нет, создайте его на своем компьютере командой ssh-keygen -t ed25519 и вставьте в панель содержимое файла ~/.ssh/id_ed25519.pub. Когда статус станет активным, скопируйте публичный IP из карточки сервера и проверьте подключение по SSH:

$ ssh root@<IP>

При успешном подключении отобразится приветствие системы:

Welcome to Ubuntu 24.04.5 LTS (GNU/Linux 6.8.0-139-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro
Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status

root@jenny:~#

Подготовка сервера

Jenkins на Ubuntu устанавливается из пакетов и требует Java 21 или новее. Перед установкой обновим систему и поставим зависимости.

Сначала подтянем список пакетов и установим обновления безопасности:

apt update && apt upgrade -y

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

  • git — для клонирования репозиториев;

  • curl и wget — для загрузки ключей и скриптов;

  • fontconfig и openjdk-21-jre — среда исполнения Java и шрифтовые зависимости, без которых Jenkins может не запуститься.

Установим все одной командой:

apt install -y git curl wget fontconfig openjdk-21-jre

Проверяем, что Java доступна:

root@jenny:~# java -version

В выводе должна отобразиться версия OpenJDK 21:

openjdk version "21.0.12.1" 2026-08-18
OpenJDK Runtime Environment (build 21.0.12.1+1-1-24.04.4-Ubuntu)
OpenJDK 64-Bit Server VM (build 21.0.12.1+1-1-24.04.4-Ubuntu, mixed mode, sharing)

Jenkins по умолчанию слушает порт 8080. Открывать его для всего интернета не стоит — к веб-интерфейсу подключимся через SSH-туннель в следующем разделе. Настроим базовый сетевой экран (файрвол) на сервере.

На минимальном образе Ubuntu утилита ufw может быть не установлена, в таком случае ее необходимо поставить:

apt install -y ufw

Разрешаем входящие подключения по SSH:

ufw allow OpenSSH

Включаем файрвол:

ufw enable

Проверяем, что файрвол запущен и правило для SSH применено:

ufw status

Базовая подготовка завершена: пакеты обновлены, Java 21 установлена, доступ по SSH ограничен файрволом. Можно ставить Jenkins.

Установка Jenkins

Установим Jenkins из официального репозитория, предварительно добавив его GPG-ключ для проверки подлинности пакетов. Это позволит получать актуальные обновления напрямую через пакетный менеджер apt, так как в стандартных репозиториях Ubuntu пакета jenkins нет.

mkdir -p /etc/apt/keyrings
wget -O /etc/apt/keyrings/jenkins-keyring.asc 
https://pkg.jenkins.io/debian-stable/jenkins.io-2026.key
echo "deb [signed-by=/etc/apt/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" | tee /etc/apt/sources.list.d/jenkins.list > /dev/null
apt update
apt install -y jenkins

Добавим Jenkins в автозагрузку и запустим службу:

systemctl enable --now jenkins

Проверим, что служба работает:

systemctl status jenkins

Если все в порядке, в строке Active отобразится статус active (running):

root@jenny:~# systemctl status jenkins
● jenkins.service - Jenkins Continuous Integration Server
     Loaded: loaded (/usr/lib/systemd/system/jenkins.service; enabled; preset: enabled)
Active: active (running)

Служба работает. Осталось получить доступ к веб-интерфейсу.

Первичная настройка

Порт 8080 закрыт файрволом, поэтому пробросим его через SSH-туннель. Для этого в локальном терминале нужно выполнить команду:

ssh -L 8080:localhost:8080 root@<IP>

Флаг -L пробрасывает локальный порт 8080 на порт 8080 виртуального сервера.

Теперь откроем в браузере адрес:

http://localhost:8080

Появится страница разблокировки Jenkins (Unlock Jenkins), где необходимо ввести пароль администратора.

Страница разблокировки Jenkins.

Страница разблокировки Jenkins.

Пароль хранится в файле на сервере. Откройте второе окно терминала с тем же ssh root@<IP>:

cat /var/lib/jenkins/secrets/initialAdminPassword

Скопируйте строку и вставьте в поле Administrator password и нажмите Continue. Jenkins предложит выбрать плагины. Выберите Install suggested plugins — это набор по умолчанию: поддержка Git, Pipeline и рекомендуемые интеграции.

Установка плагинов.

Установка плагинов.

После установки Jenkins предложит создать первого администратора. Заполните имя, пароль и email — это учетная запись для входа вместо временного пароля и нажмите Save and Continue.

Создание администратора.

Создание администратора.

На последнем шаге подтвердите URL-адрес сервера (оставьте http://localhost:8080 для локального туннеля или замените на реальный домен, если он настроен) и нажмите Save and Finish, а затем — Start using Jenkins.

Instance Configuration.

Instance Configuration.

Получили доступ к стартовому экрану — отсюда мы сможем запускать пайплайны, настраивать задачи и управлять инстансом.   

Дашборд Jenkins.

Дашборд Jenkins.

Jenkins готов к работе. В следующем разделе займемся созданием первого пайплайна.

Устанавливаем Jenkins на облачный сервер для автоматизации сборки приложений - 10

Перенос домена по 1 ₽

С легкостью переходите в Selectel от любого другого провайдера. Сайт продолжит работать без остановки.

Исследовать →

Создание пайплайна

Пайплайн в Jenkins — это последовательность шагов, описанная в файле Jenkinsfile, который лежит в корне репозитория. Jenkins читает его и выполняет каждую стадию: клонирует код, собирает, тестирует, публикует артефакты.

Организуем пайплайн, который клонирует публичный репозиторий, устанавливает зависимости проекта на Node.js и запускает тесты.
Нажимаем на кнопку Создать  item, вводим имя, выбираем тип Pipeline и нажимаем OK.

Создание задачи.

Создание задачи.

Jenkins откроет страницу настройки задачи, где будет секция Pipeline — описание конвейера. По умолчанию в поле Definition выбран Pipeline script — текстовое поле прямо в интерфейсе. Это удобно для экспериментов, но неудобно для реальной работы: скрипт хранится в Jenkins, а не в репозитории, его нельзя посмотреть в истории коммитов и нет возможности сделать код-ревью.

Выберите значение Pipeline script from SCM — тогда Jenkins будет читать Jenkinsfile из самого репозитория при каждой сборке.

Definition и SCM.

Definition и SCM.

В появившемся поле SCM выберите Git. Откроются поля для адреса и учетных данных.

Сначала создайте публичный репозиторий на GitHub или GitLab. Скопируйте его HTTPS-адрес (например, https://github.com/<user>/<repo>.git) и вставьте в Repository URL. Файлы проекта (Jenkinsfile, package.json, package-lock.json и src/) добавите в следующем шаге — Jenkins прочитает их при первой сборке.

Для публичного репозитория в поле Credentials оставьте none: Jenkins клонирует его без авторизации. Для приватного — нажмите Add, выберите тип Username with password, введите логин и токен доступа (Personal Access Token).

Repository URL и Credentials.

Repository URL и Credentials.

В поле Branch Specifier оставьте */main (или замените на */master, если в вашем репозитории главная ветка называется так). Jenkins будет собирать коммиты именно из нее.

В поле Script Path оставьте Jenkinsfile — Jenkins будет искать файл с таким именем в корне репозитория. Если проектов несколько или Jenkinsfile лежит в подпапке, путь можно изменить (например, ci/Jenkinsfile).

Сохраните изменения (нажмите Save).

Что должно быть в репозитории

Задача настроена и Jenkins знает, откуда брать сценарий. Теперь разберем, что должно лежать в самом репозитории. Для работы тестового проекта создайте следующую структуру файлов:

my-project/
├── src/
│   ├── math.js
│   └── math.test.js
├── package.json
├── package-lock.json
└── Jenkinsfile

package.json — конфигурационный файл, который задает имя проекта и команду запуска тестов:

{
  "name": "my-project",
  "scripts": {
    "test": "node src/math.test.js"
  }
}

src/math.js — простой код, который будем тестировать:

function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

module.exports = { add, subtract };

src/math.test.js — проверки без фреймворка. Если хотя бы одна из них не сойдется, скрипт завершится с кодом 1 — стадия Test в Jenkins станет красной:

const { add, subtract } = require('./math');

let passed = 0;
let failed = 0;

function assert(description, actual, expected) {
  if (actual === expected) {
    console.log(`  ✓ ${description}`);
    passed++;
  } else {
    console.error(`  ✗ ${description}: expected ${expected}, got ${actual}`);
    failed++;
  }
}

console.log('Running tests...n');

assert('add(2, 3) === 5', add(2, 3), 5);
assert('add(0, 0) === 0', add(0, 0), 0);
assert('subtract(5, 3) === 2', subtract(5, 3), 2);
assert('subtract(0, 1) === -1', subtract(0, 1), -1);

console.log(`n${passed} passed, ${failed} failed`);

if (failed > 0) process.exit(1);

Файл package-lock.json нужен для выполнения команды npm ci: без него сборка упадет на установке зависимостей. Если файла еще нет, один раз выполните npm install у себя на компьютере — npm создаст lock-файл, его тоже нужно закоммитить.

Загрузите эти файлы в репозиторий, который указали в Repository URL, и сделайте git push. Дальше на сервер нужно поставить Node.js — без него npm ci на сервере просто не найдется.

Jenkinsfile описывает, что Jenkins делает при каждой сборке. Вот минимальный пример для Node.js-проекта:

pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        stage('Install') {
            steps {
                sh 'npm ci'
            }
        }
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
    }

    post {
        success { echo 'Все тесты прошли.' }
        failure { echo 'Сборка завершилась с ошибкой.' }
    }
}

Разберем структуру файла:

  • agent any — Jenkins выберет любого доступного агента. Пока у вас один сервер, сборка выполняется на контроллере. Если позже подключите агентов, установите Node.js на всех узлах, где может запускаться пайплайн.

  • stages — список стадий. Каждая stage представляет собой отдельный шаг, который отображается в интерфейсе.

  • sh — выполнить shell-команду на сервере. Сюда можно подставлять любые команды: npm ci, go build, pytest, docker build.

  • post — блок, который выполняется после всех стадий: при успехе (success) или ошибке (failure). Здесь можно отправить уведомление в Slack, очистить рабочую директорию или опубликовать артефакты.

Установка Node.js

Jenkins не устанавливает окружение проекта автоматически: Java нужна только для работы Jenkins, а npm ci выполняется в shell на сервере. Node.js нужно установить на виртуальную машину отдельно, до первой сборки.

На облачном сервере выполните:

curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs

Проверьте, что все на месте:

node -v
npm -v

Если проект на другом стеке — принцип тот же: Go, Python, Docker — все ставится на сервер до первого запуска пайплайна.

Запускаем первую сборку

Вернитесь в Jenkins, откройте задачу и нажмите Собрать сейчас. В Pipeline overview можно отследить ход выполнения этапов.

Раздел Pipeline overview.

Раздел Pipeline overview.

Если все блоки окрасятся в зеленый цвет — конвейер работает и успешно проходит все шаги. Убедитесь, что в Console Output видно, как Jenkins клонировал репозиторий, установил зависимости через npm ci и выполнил тесты.

Автозапуск сборок

Кнопка Собрать сейчас запускает пайплайн вручную. Для автоматического запуска при появлении новых коммитов необходимо настроить опрос репозитория (Poll SCM).

Откройте настройки задачи, найдите раздел Triggers и включите Опрашивать SCM об изменениях. В поле Расписание укажите, как часто проверять репозиторий.

Создание триггера.

Создание триггера.
H/5 * * * *

Это примерно раз в пять минут (cимвол H разносит время по минутам и снижает одновременные обращения к Git-серверу). Сохраните изменения. Теперь достаточно сделать git push — в течение нескольких минут появится новая сборка.

Альтернативный способ запуска сборок — настройка вебхука. В этом случае Git-хостинг автоматически уведомляет Jenkins о появлении новых коммитов, избавив от необходимости постоянно опрашивать репозиторий. Однако этот подход требует прямого доступа к Jenkins из интернета, чтобы GitHub или GitLab могли отправить HTTP-запрос. В нашей конфигурации веб-интерфейс открыт только через SSH-туннель, снаружи его нет — webhook до сервера не дойдет. Если решите открыть Jenkins наружу, поставьте reverse proxy с HTTPS и уже потом добавьте webhook в репозитории. Для старта хватит опроса SCM.

Заключение

Мы подняли Jenkins на облачном сервере в Selectel и собрали первый рабочий пайплайн: Jenkins читает Jenkinsfile из репозитория, устанавливает зависимости и запускает тесты. База для CI/CD готова.

Как развивать конвейер:

  • Обновляйте пакет через стандартный менеджер apt update && apt upgrade jenkins.

  • Регулярно сохраняйте содержимое директории /var/lib/jenkins (настройки, задачи, история сборок).

  • Если ресурсов станет мало, вернитесь к разделу про требования: увеличьте ресурсы сервера или вынесите сборки на агентов.

Дальше можно подумать в сторону плагинов и автоматизации под ваш стек: Docker, деплой, уведомления.

Автор: marbleblazer

Источник

Оставить комментарий