Вы всё ещё деплоите 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 в репозиторий.
- В репозитории GitHub зайдите в Settings → Webhooks →