네트워크 캠퍼스/3차 프로젝트

일반 배포 방식으로 앱 서버 두 개에 배포하기

gayeon_ 2024. 8. 9. 09:37

 

서버 하나에만 배포하는 코드

pipeline {
    tools {
        gradle "GRADLE"
    }
    agent any
    stages {
        stage('Clone') {
            steps {
                git branch: 'main', url: 'git 레포지토리'
            }
        }

        stage('Build') {
            steps {
                sh './gradlew clean build'
                sh 'pwd'
                sh 'ls'
                sh 'cd build'
                sh 'pwd'
                sh 'ls'
            }
        }

        stage('Deploy') {
            steps {
                script {
                    def appServerIp = 'ip'
                    def jarFilePattern = 'jar 경로'
                    def jarFile = sh(script: "ls $jarFilePattern | grep -v plain", returnStdout: true).trim()
                    def deployPath = '/home/ubuntu'

                    sshagent(['credential key 이름']) {
                        // 이전 JAR 파일 삭제
                        sh "ssh -o StrictHostKeyChecking=no ubuntu@$appServerIp 'rm -f $deployPath/파일명.jar'"

                        // 새 JAR 파일 전송
                        sh "scp -o StrictHostKeyChecking=no $jarFile ubuntu@$appServerIp:$deployPath/"

                        // JAR 파일 실행
                        def jarFileName = jarFile.split('/').last()
                        def remoteJarFile = "$deployPath/$jarFileName"
                        def runAppCommand = "nohup java -jar $remoteJarFile > $deployPath/log.log 2>&1 &"

                        sh "ssh -o StrictHostKeyChecking=no ubuntu@$appServerIp '$runAppCommand'"

                        // 애플리케이션 시작 로그 확인
                        sleep 10
                        sh "ssh -o StrictHostKeyChecking=no ubuntu@$appServerIp 'cat $deployPath/log.log'"
                    }
                }
            }
        }
    }
    post {
        success {
            echo "Build and deployment succeeded."
        }
        failure {
            echo "Build or deployment failed."
        }
    }
}

 

Clone 단계

  • git 레포지토리의 main 브랜치에서 애플리케이션을 클론하고 gradle로 빌드를 한다. 

 

Deploy 단계

  • 배포할 앱 서버의 ip를 appServerIp에 정의하고  빌드된 jar 파일의 경로를 jarFilePattern에 정의한다.
  • jarFile에는 jarFilePattern에서 jar 파일을 찾아 저장한다.
  • deployPath에는 원격 서버에서 jar 파일을 배포할 경로를 작성한다.
  • 원격서버로의 jar 파일 전송 및 실행을 위한 ssh 접속을 위해 sshagent를 사용한다.

 

 

서버 두 개에 배포하는 코드

pipeline {
    tools {
        gradle "GRADLE"
    }
    agent any
    stages {
        stage('Clone') {
            steps {
                git branch: 'main', url: 'git 레포지토리 주소'
            }
        }

        stage('Build') {
            steps {
                sh './gradlew clean build'
                sh 'pwd'
                sh 'ls'
                sh 'cd build'
                sh 'pwd'
                sh 'ls'
            }
        }

        stage('Deploy') {
            steps {
                script {
                    def appServerIp = ['app1 ip', 'app2 ip']
                    def deployPath = '/home/ubuntu'
                    def jarFilePattern = 'jar 경로'
                    def jarFile = sh(script: "ls $jarFilePattern | grep -v plain", returnStdout: true).trim()
                    
                    for (ip in appServerIp) {
                        sshagent(['credential key 이름']) {
                            // 디버깅을 위한 출력
                            echo "Deploying to $ip"
                            
                            // 기존 Java 프로세스 종료
                            sh """
                                ssh -o StrictHostKeyChecking=no ubuntu@$ip '
                                pid=\$(pgrep -f "java -jar $deployPath/파일명.jar")
                                if [ -n "\$pid" ]; then
                                    echo "Stopping existing Java process with PID: \$pid"
                                    kill -9 \$pid
                                else
                                    echo "No existing Java process found."
                                fi
                                '
                            """

                            // 새 JAR 파일 전송
                            sh "scp -o StrictHostKeyChecking=no $jarFile ubuntu@$ip:$deployPath/"

                            // JAR 파일 실행
                            def jarFileName = jarFile.split('/').last()
                            def remoteJarFile = "$deployPath/$jarFileName"
                            def runAppCommand = "nohup java -jar $remoteJarFile > $deployPath/log.log 2>&1 &"
                            
                            sh "ssh -o StrictHostKeyChecking=no ubuntu@$ip '$runAppCommand'"

                            // 애플리케이션 시작 로그 확인
                            sleep 10
                            sh "ssh -o StrictHostKeyChecking=no ubuntu@$ip 'cat $deployPath/log.log'"
                        }
                    }
                }
            }
        }
    }
    post {
        success {
            echo "Build and deployment succeeded."
        }
        failure {
            echo "Build or deployment failed."
        }
    }
}

 

한 서버에만 배포하는 코드와 비슷하지만 다른 점은 두 개의 서버에 배포하기 위해 appServerIp 리스트를 사용했다.

또한 한 서버에만 배포하는 코드에서는 기본 jar 파일을 삭제하고 새로운 jar 파일을 전송한 후 원격 서버에서 jar 파일을 실행하지만 이 코드에는 원격 서버에서 기존 java 프로세스가 실행 중이라면 프로세스를 종료하도록 했다.

어느 서버에 배포중인지 확인하기 위해 echo 구문도 추가했다.

 

 

 

두 서버에 모두 배포되었다.

다음에는 롤링, 블루/그린 방식으로 무중단 배포할 수 있도록 코드를 수정할 것이다.