개발 기록

> [ CI/CD ] Docker & Jenkins & Spring boot CI/CD - 4. Github Webhook 설정, 젠킨스 파이프라인 & Dockerfile 작성 본문

인프라

> [ CI/CD ] Docker & Jenkins & Spring boot CI/CD - 4. Github Webhook 설정, 젠킨스 파이프라인 & Dockerfile 작성

1z 2024. 3. 8. 19:14

 

 

 

 

 

  •  

1. Github Webhook  생성 

※ Webhook
특정 이벤트 발생했을 때 다른 서비스나 응용프로그램으로 알림을 보내는 기능

※ GitHub Webhook
웹훅은 GitHub에서 특정 이벤트가 발생할 때마다 외부 웹 서버에 알림을 전달하는 방법

 

Github Repository -> Settings  -> Webhooks ->  Add Webhook

 

Payload URL : 페이로드를 수신하는 URL 

- [Jenkins Server URL]:[Jenkins Server 포트]/github-webhook/

Content type 페이로드를 수신할 데이터 형식 선택

- application/json : 페이로드를 POST Request Body 에 담아 전달한다. ( {key: value} )

- application/x-www-form-urlencoded : 페이로드를 form parameter 로 전달한다. ( key=value&key=value )

③ Secret : 선택사항

: 비밀번호를 사용하면, 수신요청을 Github 에서 발생하는 요청으로만 제한 할 수 있다. (참고)

④ 트리거 할 이벤트 

⑤ Webhooks 생성후 즉시 활성화 여부

Webhooks 추가

 


2. 도커 파이프라인 플러그인 설치  

 

Dashboard > Jenkins 관리 > 플러그인 관리 > 설치된 플러그인 > docker pipeline 검색 

도커 파이프라인 플러그인이 설치되어있지 않다면 설치를 진행한다. 

 

* Docker pipeline : Jenkins Pipeline 프로젝트에서 Docker 이미지를 빌드, 테스트 및 사용할 수 있는 Jenkins 플러그인

 

 

 


3. Jenkins Pipeline 시작하기  

(1) Pipeline 설정  

 

- Pipeline script from SCM : 프로젝트 내부에서 파일로 관리하는 Pipeline 스크립트

 

 

- Pipeline  스크립트 파일의 경로를 기입한다. 일반적으로 스크립트 파일은 Jenkinsfile 이라고 하며 프로젝트 루트에 위치한다.

- Git Branch 를 Job Parameter로 지정하고자 한다면,  'Lightweight checkout' 을 비활성화한다. 

* Lightweight checkout' : 전체 저장소가 아닌 저장소에서 특정 파일을 가져올 수 있는 Jenkins 기능으로 분기 참조 이름이 명확할 때 발생한다. 

.

 

 


4. Jenkins Pipeline 작성 

 

(1) Pipeline 구문 타입   

선언적 파이프 라인 구문 (Declarative pipeline syntax)

: pipeline 블록이 전체 파이프라인에서 수행되는 모든 작업을 정의

 

스크립트 파이프 라인 구문 (Scripted Pipeline syntax)

: 하나 이상의 node 블록이 전체 파이프라인에서 핵심작업 수행

 

 

 

(2) Pipeline 구성  

Pipeline : 선언적 파이프라인 구문의 핵심 부분

Node : 스크립트 파이프라인 구문의 핵심 부분

Stage작업의 집합, 작업의 개념별로 구분한다. (ex.빌드, 테스트, 배포) 

: stage 블록은 전체 파이프라인 단계를 통해 수행되는 작업의 하위 집합을 나타내며 전체 파이프라인의 흐름에서 특정한 시점에 실행이 필요한 것들을 묶을 수 있다.

Step : 특정 시점에 수행할 단일 작업 (ex. 쉘명령어)

 

 

(3) The Declarative Pipeline 작성 (참고)

☞ 작성 규칙

- 파이프라인의 최상위 레벨은  pipeline { } 블록 이어야 한다.

- 명령문 구분 기호로 세미콜론을 사용할 수 없다. 각 명령문은 한 줄에 하나씩 있어야 한다.

- 블록은 Sections, Directives, Steps, 할당문 으로만 구성되어야 한다.

- 속성 참조 문은 인수 없는 메서드 호출로 처리된다. (ex. input())

 

 

(4) CI/CD 선언적 파이프라인 작성

- 이미 프로젝트에 gradle 실행파일인 gradlew가 포함되어있기 때문에 별도로 gradle을 설치하지 않고 gradlew를 사용하도록 작성하겠습니다.

//Jenkins file (선언적 파이프라인)

pipeline {
    agent any
    stages {
        // git 에서 소스 다운로드
        stage('Git Checkout') {
            steps {
                sh 'echo "=== Git Clone ==="'
                git credentialsId: 'Github',
                    branch: 'master',
                    url: 'https://github.com/user/server.docker.git'
            }

            // 스테이지가 끝난 이후의 결과에 따른 후속 조치
            post {
                failure {
                    sh 'echo "Fail Cloned Repository"'
                }
            }
        }


        // gradle build&Test
        // 프로젝트 내부에 gradle 실행파일인 gradlew가 포함되있어서 gradle을 따로 설치하지 않고 gradlew 사용
        stage('Build Gradle') {
            steps {
                sh 'echo "=== Build Gradle Start ==="'
                sh 'chmod +x ./gradlew'
                sh './gradlew clean build -x test'
            }
            post {
                failure {
                    sh 'echo "Build Gradle Fail"'
                }
            }
        }

        // Docker Hub 에 이미지 푸시
        stage('Docker Hub Image build & Push') {
            steps {
                sh 'echo "Docker Hub Image Push Start"'
                script {
                    docker.withRegistry('', 'docker') {
                        def customImage = docker.build("user/springboot:${env.BUILD_ID}")
                        customImage.push()
                    }
                }
            }
        }
        
        // 배포
        // 원격지 서버에서 해당 이미지를 다운받고 실행한다.
//         stage('Remote Server Docker Pull') {
//             steps([$class: 'BapSshPromotionPublisherPlugin']) {
//                 sh 'echo "Remote Server Docker Pull Start"'
//                 sshPublisher(
//                     continueOnError: false,
//                     failOnError: true,
//                     publishers: [
//                         sshPublisherDesc(
//                             configName: "remote-server",
//                             verbose: true,
//                             transfers: [
//                                 sshTransfer(
//                                     execCommand: "sh /home/scripts/spring-container.sh"
//                                 )
//                             ]
//                         )
//                     ]
//                 )
//             }
    }
}

 

 

 


5. 이미지 빌드를 위해 Dockerfile 작성 

FROM openjdk:17-alpine

LABEL description = "Jenkins+Docker CI/CD API"
ENV TZ=Asia/Seoul

EXPOSE 8181

# 젠킨스가 빌드한 결과물은 target 디렉토리에 배치된다.
COPY ./build/libs/docker-0.0.1-SNAPSHOT.jar /home/build/libs/docker-0.0.1-SNAPSHOT.jar

# 명령어가 실행되는 위치
WORKDIR /home/build/libs

# 컨테이너 실행 시 실행되는 명령어
ENTRYPOINT ["java","-jar","docker-0.0.1-SNAPSHOT.jar"]

 

 

 

 

 

 

 

 

참고

https://www.jenkins.io/doc/book/pipeline/jenkinsfile/

https://jojoldu.tistory.com/313

https://www.jenkins.io/doc/book/pipeline/getting-started/