[ 잎 사이 ] Jenkins로 CD 구축하기 ( private 레포지토리 )

5tr1ker·2024년 11월 19일
0

CI/CD

목록 보기
5/5
post-thumbnail

개요

시스템에 무중단 배포를 적용하여, develop에 기능을 커밋했을 경우 자동으로 테스트 서버로 최신화할 수 있는 로직을 만들어 봅시다.

CD 순서는 다음과 같이 설계를 기획했습니다.
1. Main 브랜치에 Merge
2. Jenkins가 WebHook을 받고 Git Repository 에서 최신 데이터를 Clone
3. 기존 시스템에 돌아가는 서비스 강제 종료
4. 최신 데이터를 build 하고 build된 project를 실행

코드

pipeline {
    agent any

    stages() {
        stage('Git clone') {
            steps {
                git branch: 'develop', credentialsId: '*****', url: 'https://github.com/KU-student-saver/ku-server'
            }
        }
        
        stage('Kill Process') {
            steps {
                script {
                    catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                        // 'netstat' 명령어 실행 결과 (출력) 저장
                        def output = bat(script: 'netstat -ano | find "8080"', returnStdout: true).trim()
        
                        // PID 추출 (결과에서 공백으로 구분된 마지막 값)
                        def pid = output.tokenize().last()
                            
                        // PID 출력 (디버깅용)
                        echo "PID to kill: ${pid}"
                            
                        // 'taskkill' 명령 실행
                        bat "taskkill /f /pid ${pid}"
                    }
                }
            }
        }
        
        stage('Gradle Build') {
            steps {
                bat 'gradlew clean bootJar'
            }
        }
        
        stage('Run Server') {
            steps {
                bat "set JENKINS_NODE_COOKIE=dontKillMe && start /b java -jar build/libs/ku-student-1.0-SNAPSHOT.jar 2>&1"
            }
        }
    }
}

설명

  1. 'Git Clone' 단계
    Private Repository 에서 project를 clone 하기 위해서는 credentialsId가 필요하기 때문에 키를 첨부하여 clone을 요청합니다.

  2. Kill Process 단계
    기존에 실행중인 서비스를 종료하기 위해 netstat -ano | find "8080" 명령어를 활용하여 실행중인 서비스의 PID번호를 얻은 다음 taskkill 명령어를 통해 Process를 제거했습니다.
    만약 Process가 없을 경우 예외가 발생하기 때문에 catchError 로직을 통해 예외 처리를 하였습니다.

  3. Gradle Build 단계
    서버를 실행할 Build 파일을 생성하기 위해 gradlew 명령어를 실행했습니다.

  4. Run Server 단계
    백그라운드에서 실행하기 위해 start /b 를 java 파일 실행 명령어 앞에 작성했습니다.
    이때 젠킨스는 작업을 완료한 이후에 실행중이던 자식 프로세스를 죽이기 때문에 set JENKINS_NODE_COOKIE=dontKillMe 명령어를 통해 프로세스가 죽이는 과정을 제외했습니다.

만약 set JENKINS_NODE_COOKIE=dontKillMe 가 없다면 서버 실행 도중에 프로세스가 죽어버리는 일이 발생합니다.

백그라운드에서 실행이 안될 때

스크립트 종료와 함께 어플리케이션도 종료되어 버린다

Jenkins의 스크립트는 정리된 step을 차례대로 실행하고 스크립트가 종료되면 실행 환경을 정리하고 종료한다. 즉, 자식 프로세스도 함께 생을 마감하게 된다.

Jenkins 환경변수 JENKINS_NODE_COOKIE=dontKillMe 추가하여 나를 죽이지말아달라고 애원하면, 백그라운드 프레세스가 종료하지 않도록 할 수 있다.

set JENKINS_NODE_COOKIE=dontKillMe && start /b java -jar build/libs/ku-student-1.0-SNAPSHOT.jar 2>&1

참고

참고 블로그 1 [ private 레포지토리에서 clone 하기 ] : https://velog.io/@bm1201/Jenkinswindow%ED%99%98%EA%B2%BD-private-repository-github-%EC%97%B0%EB%8F%99
참고 블로그 2 : https://velog.io/@parkirae/portfolio-Jenkins%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-CICD-%EA%B5%AC%EC%B6%95#gradle-jdk-git-%EC%84%A4%EC%A0%95
참고 블로그 3 : https://velog.io/@hyeonwoody/JenkinsPipeline-%EB%B0%B1%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EC%8B%A4%ED%96%89

profile
https://github.com/5tr1ker

0개의 댓글