Как установить Jenkins на сервер и настроить CI/CD пайплайн

Как установить Jenkins на облачный сервер и настроить первый CI/CD пайплайн

Пошаговый гайд по автоматизации сборки приложений. Разбираемся в архитектуре Jenkins, подбираем конфигурацию облачного сервера в Selectel, готовим окружение на Ubuntu 24.04 и пишем свой первый Jenkinsfile.

Сборка, тестирование и развертывание приложения — операции, которые приходится повторять при каждом изменении кодовой базы. С ростом проекта ручная сборка и деплой начинают отнимать время и приводят к ошибкам. Эту рутину убирает практика непрерывной интеграции и доставки (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. Этого с запасом хватит для контроллера и небольших сборок на нем.

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

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

Интерфейс Панели управления Selectel, вкладка Продукты.
Разделы панели управления.

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

Кнопка Создать сервер в разделе Облачные серверы интерфейса Панели управления 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
Установка плагинов.

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

Форма создания первого пользователя-администратора в веб-интерфейсе Jenkins.
Создание администратора.

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

Страница настройки URL-адреса инстанса (Instance Configuration) в Jenkins.
Instance Configuration.

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

Главный рабочий стол (дашборд) веб-интерфейса Jenkins после завершения первичной настройки.
Дашборд Jenkins.

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

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

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

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

Страница создания элемента (Item) в Jenkins с выбором типа задачи.
Создание задачи.

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

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

Настройка источника пайплайна (Definition и SCM) в конфигурации Jenkins.
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).

Настройка URL-адреса Git-репозитория и учетных данных в Jenkins.
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 можно отследить ход выполнения этапов.

Успешное выполнение всех этапов CI/CD пайплайна в интерфейсе Jenkins.
Раздел Pipeline overview.

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

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

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

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

Настройка триггера опроса SCM (Poll SCM) с расписанием в Jenkins.
Создание триггера.

      H/5 * * * *

Это примерно раз в пять минут (Символ 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, деплой, уведомления.