CI/CD pipeline для Java: настройка с нуля, чтобы не бояться деплоя

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Вы всё ещё деплоите Java-приложение по SSH?

Если вы когда-нибудь настраивали Java-проект в продакшене вручную — mvn clean install, scp на сервер, убивание процесса, запуск заново — вы знаете это чувство: вроде всё работает, но каждый деплой — как квест с боссом. Один забытый флаг, одна неверная версия Java — и приложение падает, а вы получаете сообщение «Сервер не отвечает» в 3 часа ночи.

Сегодня мы разберём, как построить CI/CD pipeline для Java с нуля. Неважно, используете вы Spring Boot, Micronaut или старый добрый Java EE — этот пайплайн спасёт ваши нервы и время. Мы будем использовать Jenkins, Maven, Docker и GitHub. Всё будет по-настоящему: с кодом, конфигами и живыми примерами.


Что такое CI/CD и зачем это Java-разработчику?

CI/CD (Continuous Integration / Continuous Delivery) — это не просто модное слово. Это процесс, который превращает ваш код из «написал на коленке» в «работает стабильно на сервере» без вашего участия.

  • Continuous Integration — каждый ваш коммит автоматически собирается и тестируется. Если тесты падают — вы узнаёте об этом мгновенно, а не через неделю.
  • Continuous Delivery — после успешной сборки код автоматически разворачивается на тестовом или боевом сервере.

Для Java это особенно важно: сборка через Maven/Gradle, прогон unit-тестов, интеграционных тестов, проверка стиля кода — всё это можно и нужно автоматизировать. Иначе вы будете тратить часы на рутину вместо того, чтобы писать фичи.


Шаг 1. Подготовка окружения: что нам понадобится

Прежде чем писать пайплайн, давайте убедимся, что у нас есть все инструменты. Для нашего CI/CD pipeline для Java потребуется:

  • GitHub (или GitLab/Bitbucket) — репозиторий с кодом.
  • Jenkins — сервер автоматизации. Можно поднять локально или на VPS.
  • Maven — сборщик Java-проекта.
  • Docker — для контейнеризации приложения.
  • Сервер (или облако) — куда будем деплоить.

Установим Jenkins на Ubuntu (если у вас другая ОС — не страшно, принцип тот же):

sudo apt update
sudo apt install openjdk-11-jdk
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt update
sudo apt install jenkins
sudo systemctl start jenkins

После установки откройте http://ваш-сервер:8080 и выполните первоначальную настройку. Не забудьте установить плагины: Git, Maven Integration, Docker Pipeline, Blue Ocean (для красивого интерфейса).


Шаг 2. Пишем простой Java-проект (Spring Boot)

Чтобы было на чём тренироваться, создадим минимальный Spring Boot-сервис. Если у вас уже есть проект — просто пропустите этот шаг.

// Main.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @GetMapping("/")
    public String hello() {
        return "Hello from CI/CD pipeline!";
    }
}

Не забудьте pom.xml с зависимостями. Обычный Spring Boot starter + Maven compiler plugin. Это наш подопытный кролик.


Шаг 3. Создаём Jenkinsfile — сердце пайплайна

Jenkinsfile — это декларативный или скриптовый файл, который описывает все этапы вашего пайплайна. Мы будем использовать декларативный синтаксис — он проще для понимания.

Создайте в корне проекта файл Jenkinsfile:

pipeline {
    agent any

    tools {
        maven 'Maven-3.8.6'
        jdk 'JDK-11'
    }

    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/ваш-username/ваш-репозиторий.git'
            }
        }

        stage('Build & Test') {
            steps {
                sh 'mvn clean test'
            }
            post {
                success {
                    echo 'Сборка и тесты прошли успешно!'
                }
                failure {
                    echo 'Тесты упали. Проверьте код.'
                }
            }
        }

        stage('Package') {
            steps {
                sh 'mvn package -DskipTests'
            }
        }

        stage('Docker Build & Push') {
            steps {
                script {
                    docker.build("my-java-app:${BUILD_NUMBER}")
                    docker.withRegistry('https://hub.docker.com', 'docker-hub-credentials') {
                        docker.image("my-java-app:${BUILD_NUMBER}").push()
                    }
                }
            }
        }

        stage('Deploy') {
            steps {
                sh '''
                    ssh user@server "docker pull my-java-app:${BUILD_NUMBER} && 
                    docker stop my-app || true && 
                    docker rm my-app || true && 
                    docker run -d --name my-app -p 8080:8080 my-java-app:${BUILD_NUMBER}"
                '''
            }
        }
    }

    post {
        always {
            cleanWs()
        }
    }
}

Обратите внимание: мы сначала собираем проект, прогоняем тесты, пакуем в JAR, оборачиваем в Docker-образ, пушим в реестр и деплоим на сервер. Это классический CI/CD pipeline для Java.

Важно: для SSH-доступа к серверу нужно настроить credentials в Jenkins (SSH ключи или пароль). Без этого этап Deploy упадёт.


Шаг 4. Dockerfile для Java-приложения

Без Docker никуда. Даже если вы не фанат контейнеров — для CI/CD это стандарт. Создайте Dockerfile в корне проекта:

FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/demo-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Всё просто: берём сжатую JRE, копируем JAR, запускаем. Если используете Gradle — путь к JAR будет другим. Подстройте под свой проект.


Шаг 5. Интеграция с GitHub: Webhook и автоматический запуск

Ручной запуск пайплайна — прошлый век. Настройте GitHub Webhook, чтобы Jenkins сам реагировал на push в репозиторий.

  1. В репозитории GitHub зайдите в Settings → Webhooks →

Блоги

Рекомендаций по книгам