Gymterview
middle

Как устроен CI/CD pipeline для Java-приложения?

CI/CD pipeline — это автоматизированная цепочка сборки, тестирования и деплоя, которая для Java-приложения типично включает этапы: test, build, push image, deploy.

GitHub Actions CI/CD pipeline
name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:17-alpine
        env:
          POSTGRES_DB: testdb
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
        ports:
          - 5432:5432

    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
          cache: 'gradle'
      - name: Run tests
        run: ./gradlew test
      - name: Run checkstyle
        run: ./gradlew checkstyleMain checkstyleTest

  build-and-push:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - name: Build JAR
        run: ./gradlew bootJar
      - name: Build and push Docker image
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}

  deploy:
    needs: build-and-push
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Update Kubernetes manifest
        run: |
          cd k8s/overlays/production
          kustomize edit set image order-service=ghcr.io/${{ github.repository }}:${{ github.sha }}

Docker Compose для dev-окружения

docker-compose.yml
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: local
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/orderdb
      SPRING_KAFKA_BOOTSTRAP_SERVERS: kafka:9092
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:17-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: orderdb
      POSTGRES_USER: order
      POSTGRES_PASSWORD: order
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U order -d orderdb"]

  kafka:
    image: confluentinc/cp-kafka:7.7.0
    ports:
      - "9092:9092"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  prometheus:
    image: prom/prometheus:v2.55.0
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana:11.3.0
    ports:
      - "3000:3000"

Ключевые принципы

  • CI pipeline должен быть быстрым (менее 10 минут): кэширование зависимостей, параллельные джобы
  • Тесты в CI детерминированные: только Testcontainers или service containers
  • Docker Compose для локальной разработки полностью воспроизводит production-зависимости
  • GitOps: изменение манифестов в git автоматически приводит к деплою

Частые ошибки

  • CI pipeline длиннее 15-20 минут: разработчики мёрджат без зелёного билда
  • Отсутствие кэширования зависимостей: каждый билд скачивает все jar-файлы
  • Ручной деплой: “Вася знает, как деплоить” — single point of failure
  • Секреты в CI-файлах вместо GitHub Secrets / Vault

На собеседовании: опишите этапы pipeline: checkout, test, build JAR, build Docker image, push to registry, deploy to K8s. Упоминание GitOps (ArgoCD) и кэширования Gradle показывает production-опыт. Вопрос “Как ускорить CI?” — ответ: Gradle build cache, параллельные джобы, тонкие Docker-слои.