본문 바로가기

DevOps

Springboot(gradle) Jenkins 설정으로 Ubuntu 자동 배포하기

개요 목적

Host인 Window 서버에서 Jenkins와 Docker를 사용하여 Springboot 프로젝트를 Virtualbox에서 실행되고 있는 Ubuntu서버에 자동 배포하는 방법에 대해서 알아본다

해당 프로젝트 깃허브

Jenkins에 설정할 전체 6가지 동작은 아래 그림과 같다.

<프로젝트 깃허브 커밋 후 자동 빌드 배포 영상>

1. Git에서 최신 소스 다운로드

https://www.jenkins.io/doc/pipeline/steps/git/

해당 플러그인을 사용하여 git에서 최신 소스 코드를 다운 받는 declarative pipeline script를 작성

C:\ProgramData\Jenkins\.jenkins\workspace에 디렉토리에 해당 프로젝트를 다운 받은 것을 확인할 수 있다.

pipeline {
    agent any
    stages {
        // git에서 repository clone
        stage('Prepare') {
            steps {
                echo 'Clonning Repository'
                //해당 플러그인 동작으로 url에 해당하는 최신 소스코드를 저장한다.
                git url: '<https://github.com/dae0hwang/letsgo>',
                        branch: 'master'
            }
            post {
                success {
                    echo 'Successfully Cloned Repository'
                }
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
    }
}

2. jar 파일을 만들기 위해 gradle build 실행

pipeline script dir() 명령어로 gradlew 파일 있는 곳으로 이동 후 bat 명령어로 window 쉘 스크립트 gradlew clean build를 실행하여 최신 소스 버전의 jar파일을 생성한다.

pipeline {
    agent any
    stages {
        stage('Prepare') {
          //생략
        }
        // gradle build
        stage('Bulid Gradle') {
            agent any
            steps {
                echo 'Bulid Gradle'
                //최신 소스 gradlew 파일이 있는 곳으로 이동 후 jar파일 생성
                dir ('../jenkins-test') {
                    bat 'gradlew clean build'
                }
            }
            post {
                success {
                    echo "SuccessfulAZly Build gradle"
                }
                failure {
                    echo "Fail to build gradle"
                    error 'This pipeline stops here...'
                }
            }
        }
    }
}

3. Junit Test 결과 Jenkins report 연결하기

https://www.jenkins.io/doc/pipeline/tour/tests-and-artifacts/

해당 문서를 참고하여, gradle build 후 생성 되는 파일 위치를 Junit에 지정을 하면 jenkins에서 테스트 결과를 확인할 수 있다.

pipeline {
    agent any
    stages {
        stage('Prepare') { 
        }
        stage('Bulid Gradle') {
        }
        // test repont
        stage('JUnit Test'){
            steps{
                echo 'Test Result'
                junit '**/build/test-results/test/*.xml'
            }
        }
    }
}

4.Window에서 docker image 생성하기

https://docs.cloudbees.com/docs/cloudbees-ci/latest/pipelines/docker-workflow

docker pipeline plugin을 사용하여 프로젝트 내부의 dockerfile 대로 docker image를 생성한다.

만든 이미지는 환경 변수에 저장하여 docker hub push 할 때 사용할 수 있다.

pipeline {
    agent any
		
    //만든 이미지를 환경 변수에 저장하여 다른 stage에서도 사용할 수 있도록 설정
    environment {
        dockerImage = ''
    }

    stages {
        stage('Prepare') {  
        }
        stage('Bulid Gradle') { 
        }
        stage('JUnit Test'){
        }
        // docker build
        stage('Bulid Docker') {
            agent any
            steps {
                echo 'Bulid Docker'
                //해당 소스코드 dockerfile이 있는 곳으로 이동 후
                dir ('../jenkins-test') {
                    script {
                        //명령어를 이용해 docker build를 실행
                        //환경 변수에 만든 이미지를 담아둔다. 
                        dockerImage = docker.build 'hwangdy/docker-test'
                    }
                }
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
    }
}

5. docker hub에 이미지 전송

만들어 놓은 이미지를 운영 서버인 ubuntu 서버에서 다운 받을 수 있도록 dockerhub에 저장해야 한다.

먼저 dockerhub의 로그인 정보를 저장할 credential을 설정한다. Dashboard → Jenkins 관리 → Credentials → Global credential 위치로 들어가 Add Credential 버튼을 클릭한다.

kind 필드는 username with password를 선택하고

username에는 dockerhub email이 아닌 docker username을 입력한다.

password는 dockerhub의 password 입력

ID는 해당 credential를 구분할 수 있는 식별자를 입력하면 된다.

이제 해당 credentail 정보를 환경 변수에 저장하고 전에 만들어 놓은 image 파일을 docker hub에 전달한다.

pipeline {
    agent any
		//환경 변수에 credential id를 작성하여 username password 정보를 저장한다.
    environment {
        registryCredential = 'DockerHub_IdPwd'
        dockerImage = ''
    }

    stages {  
        stage('Prepare') {
        }
        stage('Bulid Gradle') {
        }
        stage('JUnit Test'){
        }
        stage('Bulid Docker') {
        }
        // docker push
        stage('Push Docker') {
            steps {
                echo 'Push Docker'
                script {
                    //docker 명령어를 통해 전에 만들어 놓은 image를 push한다.
                    docker.withRegistry('', registryCredential) {
                        dockerImage.push()
                    }
                }
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
    }
}

6. SSH를 사용하여 Ubuntu image 다운 후 실행

이제 마지막 단계 window jenkins에서 SSH 연결을 통해 Ubuntu에게 실행할 명령어를 전달하여 docker image를 다운 받고 실행하는 과정을 알아보자.

https://www.jenkins.io/doc/pipeline/steps/ssh-steps/

jenkins pipline에서 ssh 연결을 위해 SSH Pipeline Steps plugin을 사용했다.

접속할 ubuntu id 와 password를 위와 같은 방식으로 credentials에 저장 하고 pipeline 환경 변수로 가져온다.

ssh-steps를 통해 접속 후 "bash jenkins.sh" 실행 파일을 실행하는 명령을 저장한다.

pipeline {
    agent any
    environment {
        ubuntuId = credentials('ubuntu_id')
        ubuntuPass = credentials('ubuntu_pass')
    }
    stages {
        stage('Prepare') {
        }
        stage('Bulid Gradle') {
        }
        stage('JUnit Test'){
        }
        stage('Bulid Docker') {
        }
        stage('Push Docker') {
        }
        // shh - deploy
        stage('SSH') {
            steps {
                script {
                    def remote = [:]
                    remote.name = 'test'
                    remote.host = '127.0.0.5' //ubuntu 포트 포워딩 IP port는 default로 22
                    remote.user = ubuntuId
                    remote.password = ubuntuPass
                    remote.allowAnyHosts = true
                    stage('Remote SSH') {
                        //원하는 명령어 작성
                        sshCommand remote: remote, command: "bash jenkins.sh" 
                    }
                }
            }
        }
    }
}

ubuntu에 저장된 jenkins.sh 파일 내용은 아래와 같다.

기존의 도커 컨테이너와 이미지 파일을 삭제 후 최신 버전의 컨테이너를 다운받고 실행한다.

최종 pipeline script는 https://github.com/dae0hwang/letsgo/blob/master/Jenkinsfile 에서 확인할 수 있다.