Напомним об инструментах для построения CI/CD пайплайнов:
- Jenkins: дедушка CI/CD инструментов, мощный и настраиваемый.
- GitHub Actions: встроено в GitHub, удобно и быстро.
- GitLab CI/CD: отличное средство для пайплайнов, если вы используете GitLab.
- CircleCI: облачное решение, простое в настройке.
- Bitbucket Pipelines: инструмент для CI/CD в экосистеме Atlassian.
Для этой лекции мы будем использовать GitLab CI/CD – он прост, нагляден и отлично интегрируется с Docker.
Подготовка к работе
Шаг 1: Создайте репозиторий в GitLab
Для начала убедитесь, что у вас уже есть репозиторий, содержащий ваше Spring Boot приложение. Если нет, создайте новый репозиторий и загрузите туда весь проект.
Шаг 2: Настройка файла .gitlab-ci.yml
GitLab CI/CD использует файл .gitlab-ci.yml, чтобы определить, как запускать пайплайн. Этот файл должен находиться в корне репозитория.
Создание CI/CD пайплайна
Шаг 1: Минимальная конфигурация .gitlab-ci.yml
Начнем с простого примера, который запускает Java-тесты и собирает Spring Boot приложение:
stages: # Определяем стадии пайплайна
- test
- build
test-job: # Задача для стадии тестирования
stage: test
image: maven:3.8.6-jdk-11 # Используем образ с Maven и JDK
script:
- mvn test # Запуск тестов
build-job: # Задача для стадии сборки
stage: build
image: maven:3.8.6-jdk-11
script:
- mvn package -DskipTests # Сборка jar-файла
artifacts:
paths:
- target/*.jar # Сохраняем jar-файл как артефакт
stages: определяют последовательность выполнения пайплайна. Сначалаtest, потомbuild.image: указывает Docker-образ, который будет использоваться для выполнения задачи. В нашем случае это Maven + JDK.script: команды, которые выполняются в рамках задачи.
Шаг 2: Добавляем Docker в пайплайн
Теперь добавим стадию, которая собирает Docker-образ и пушит его в Docker Hub.
stages:
- test
- build
- dockerize
dockerize-job:
stage: dockerize
image: docker:latest # Используем Docker-образ
services:
- docker:dind # Docker-in-Docker для управления контейнерами
before_script: # Авторизация в Docker Hub
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
script:
- docker build -t $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA . # Сборка образа
- docker push $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA # Публикация образа
Обратите внимание:
servicesвключаетdocker:dind, чтобы GitLab Runner мог запускать Docker-команды.before_scriptиспользуется для выполнения предварительных действий, таких как логин в Docker Hub.$CI_COMMIT_SHORT_SHA— переменная, содержащая первые 8 символов хэша коммита. Это позволяет уникально идентифицировать образ.
Шаг 3: Добавляем деплой в облако
Предположим, мы деплоим приложение на сервер через SSH. Для этого добавим стадию deploy:
stages:
- test
- build
- dockerize
- deploy
deploy-job:
stage: deploy
image: ubuntu:latest
before_script:
- apt-get update && apt-get install -y ssh # Устанавливаем SSH-клиент
script:
- ssh $DEPLOY_USER@$DEPLOY_HOST "docker pull $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA && docker stop my-spring-app || true && docker rm my-spring-app || true && docker run -d --name my-spring-app -p 8080:8080 $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA"
Что здесь происходит:
- Через SSH подключаемся к серверу.
- Тянем свежий Docker-образ нашего приложения.
- Останавливаем и удаляем старый контейнер (если он был запущен).
- Запускаем новый контейнер.
Переменные окружения
Для работы пайплайна нам нужно задать переменные окружения в GitLab:
$DOCKER_USERNAME— имя пользователя Docker Hub.$DOCKER_PASSWORD— пароль от Docker Hub.$DEPLOY_USER— SSH пользователь для деплоя.$DEPLOY_HOST— хост, на который деплоится приложение.
Вы можете настроить их в разделе Settings → CI/CD → Variables вашего GitLab проекта.
Полный файл .gitlab-ci.yml
В итоге у нас получается такой файл:
stages:
- test
- build
- dockerize
- deploy
test-job:
stage: test
image: maven:3.8.6-jdk-11
script:
- mvn test
build-job:
stage: build
image: maven:3.8.6-jdk-11
script:
- mvn package -DskipTests
artifacts:
paths:
- target/*.jar
dockerize-job:
stage: dockerize
image: docker:latest
services:
- docker:dind
before_script:
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
script:
- docker build -t $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA .
- docker push $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA
deploy-job:
stage: deploy
image: ubuntu:latest
before_script:
- apt-get update && apt-get install -y ssh
script:
- ssh $DEPLOY_USER@$DEPLOY_HOST "docker pull $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA && docker stop my-spring-app || true && docker rm my-spring-app || true && docker run -d --name my-spring-app -p 8080:8080 $DOCKER_USERNAME/my-spring-app:$CI_COMMIT_SHORT_SHA"
Отладка и типичные ошибки
- Docker-in-Docker проблемы Если вы видите ошибки вроде
cannot connect to the Docker daemon, убедитесь, что сервисdocker:dindзапущен и правильно настроен. - SSH не работает Проверьте, что SSH-ключ добавлен на ваш сервер, а переменные
$DEPLOY_USERи$DEPLOY_HOSTзаданы корректно. - Проблемы с Docker Hub Если Docker Hub возвращает ошибку аутентификации, проверьте, что
$DOCKER_USERNAMEи$DOCKER_PASSWORDправильно заданы.
Все готово! Вы только что создали боевой CI/CD пайплайн для своего Spring Boot приложения. Теперь каждая новая фича будет автоматически проверена, собрана и доставлена в продакшн, пока вы пьете кофе.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ