본문 바로가기
Projects

[Slack AI Bot] 스프링 부트 CI/CD 파이프라인 구축

by hxxyeoniii 2025. 11. 18.

Slack 부재 메시지 AI 요약

카카오톡에서 제공하는 AI 요약기능을 슬랙에 붙이면 어떨까? 하는 생각에서 시작된 사이드 프로젝트이다.
 
[MVP] 주 기능

  • 메시지 수집 : 슬랙 채널의 메시지를 실시간 수집
  • 부재 감지 : 사용자가 24시간 이상 메시지를 읽지 않으면 감지(우선 24시간으로 설정)
  • AI 요약 : 놓친 메시지를 Open API로 요약
  • DM 전송 : 요약 내용을 슬랙 DM으로 전송
  • 모니터링 : Prometheus로 메트릭 수집 & Grafana로 시각화

CI/CD 파이프라인 구축

1. Spring Boot 애플리케이션 생성

  • 프로젝트명 : Slack AI Summary
  • Java 17, Spring Boot 3.5.7

 
2. Docker 컨테이너화

  • Dockerfile & docker-compose.yml & .env 생성

 
Dockerfile : 하나의 도커 이미지를 어떻게 만들 것인지 정의

FROM eclipse-temurin:17-jdk-jammy AS builder
WORKDIR /app
COPY gradlew .
COPY gradle gradle
COPY build.gradle .
COPY settings.gradle .
COPY src src
RUN chmod +x ./gradlew
RUN ./gradlew build -x test

FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

 
 
docker-compose.yml : 여러 서비스의 오케스트레이션 -> 위의 이미지로 컨테이너를 실행하는 방법 정의

version: '3.8'

services:
  # 메인 애플리케이션 (모든 profile에서 실행)
  app:
    build: .
    container_name: slack-absence-summary
    ports:
      - "8080:8080"
    environment:
      - SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN}
      - SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET}
      - SLACK_APP_TOKEN=${SLACK_APP_TOKEN}
      - SPRING_AI_OPENAI_API_KEY=${OPENAI_API_KEY}
      - SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE:-dev}
    volumes:
      - ./logs:/app/logs
    networks:
      - slack-network

  # Prometheus (monitoring profile에서만 실행)
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    networks:
      - slack-network
    profiles:
      - monitoring

  # Grafana (monitoring profile에서만 실행)
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_SERVER_ROOT_URL=http://localhost:3000
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    depends_on:
      - prometheus
    networks:
      - slack-network
    profiles:
      - monitoring

networks:
  slack-network:
    driver: bridge

volumes:
  prometheus-data:
  grafana-data:

 

Jenkinsfile ->  애플리케이션 자동으로 빌드하고 배포

pipeline {
    agent any

    environment {
        DOCKER_IMAGE = 'slack-ai-summary-app'
        CONTAINER_NAME = 'slack-absence-summary'
    }

    stages {
        stage('Checkout') {
            steps {
                echo 'Checking out code from GitHub...'
                checkout scm
            }
        }

        stage('Build') {
            steps {
                echo 'Building Docker image...'
                sh 'docker-compose build'
            }
        }

        stage('Stop Old Container') {
            steps {
                echo 'Stopping old container if running...'
                sh 'docker-compose down || true'
            }
        }

        stage('Deploy') {
            steps {
                echo 'Starting new container...'
                sh 'docker-compose up -d'
                echo 'Waiting for application to start...'
                sh 'sleep 10'
            }
        }
    }

    post {
        success {
            echo 'Deployment successful! Application is running on port 8080'
        }
        failure {
            echo 'Deployment failed!'
            sh 'docker-compose logs --tail=50 || true'
        }
        always {
            echo 'Pipeline finished'
        }
    }
}