본문 바로가기
📚 시리즈/- Jenkins와 Webhook을 이용한 CICD

[Webhook을 이용하여 CI CD 구성하기] - pipeline으로 배포하기

by Wonit 2021. 8. 31.

해당 글은 Jenkins와 Github Webhook을 이용한 CICD 파이프라인 구성하기 시리즈 입니다. 자세한 사항은 아래 링크를 참고해주세요!

 

만약 해당 실습 내용의 코드가 궁금하다면 프로젝트 깃허브 에서 확인할 수 있습니다.

 

 

이제 이 Jenkins의 마지막 시간이 되었다.

 

지난 시간까지 Continous Integration 을 수행했으니 이제는 Continous Deploy를 수행해보자!

 

목차

  • jenkins에 pipeline 생성하기
    • item 추가
    • 설정 및 script 작성
  • 테스트

 

1. Jenkins에 Pipeline 생성하기

 

젠킨스의 Pipeline 은 연속적인 이벤트 & Job 그룹을 의미한다.

 

우리가 만약 배포해야할 여러 Application 이나 관리해야할 자원이 있다면 Pipeline Script를 실행함으로 기대한 목적을 이룬다.

 

즉, 우리가 Code Commit 을 한다면 Pipeline 이용해서 Webhooks 를 감시하고 이벤트를 실행한다.

 

Pipeline Script 에서 우리가 할 것들을 명시해주는데, 이는 평범한 Groovy 형태의 코드 블럭이라고 생각해도 된다.

 

Pipeline 을 선언할 때는 다음과 같이 pipeline 블록 내부에서 정의한다.

 

pipeline {
  // Declarative 추가
}

 

이는 항상 최상위 레벨에서 다른 블록들을 감싸야 하고, 아래의 블록이 올 수 있다.

 

  • agent
    • pipeline 최상단에 위치하여, 특정 job 들을 수행할 agent 를 의미한다
    • 대표적으로는 node, docker, kubernetes 를 파라미터로 포함할 수 있다.
  • stages
    • 하나 이상의 stage를 정의하는데, stage는 해당 pipeline 이 동작할 때, 실행되는 단계를 의미한다
    • 내부적으로 steps 를 정의해줘야 한다
  • environment
    • pipeline 내부에서 key-value 형태로 사용할 수 있는 환경 변수이다.
  • parameters
    • pipeline 내부에서 특정 노드, 컨테이너를 실행시킬 때 변수를 제공해야할 때 사용한다.

 

이 개념들을 가지고 pipeline 을 구성해보자!

 

Pipeline Item 추가하기

 

Jenkins 대시보드로 들어가서 다시 새로운 Item 을 만들고 이번에는 Pipeline Item을 추가하자.

 

 

역시 Github 프로젝트를 선택한 뒤, Github Repository의 URL을 적어주자.

 

그리고 Pipeline speed/durability 에서는 Performance-optimized 로 설정해주고 Build Trigger를 Github hook trigger for GitScm Polling 으로 체크하자

 

 

Pipeline Script 작성하기

 

jenkins pipeline 을 추가할 때, 아래의 pipeline script 항목에서 다음과 같이 작성하자

 

pipeline {
    agent any
    options {
        timeout(time: 1, unit: 'HOURS')
    }
    environment {
        SOURCECODE_JENKINS_CREDENTIAL_ID = 'jenking-github-wh'
        SOURCE_CODE_URL = 'https://github.com/my-research/todo-with-cicd.git'
        RELEASE_BRANCH = 'master'
    }
    stages {
        stage('Init') {
            steps {
                echo 'clear'
                sh 'docker stop $(docker ps -aq)'
                sh 'docker rm $(docker ps -aq)'
                deleteDir()
            }
        }

        stage('clone') {
            steps {
                git url: "$SOURCE_CODE_URL",
                    branch: "$RELEASE_BRANCH",
                    credentialsId: "$SOURCECODE_JENKINS_CREDENTIAL_ID"
                sh "ls -al"
            }
        }

        stage('frontend dockerizing') {
            steps {
                sh "docker build -t todo/frontend ./frontend"
            }
        }

        stage('backend dockerizing') {
            steps {
                sh "pwd"
                dir("./backend"){
                    sh "pwd"

                    sh "gradle clean"
                    sh "gradle bootJar"

                    sh "docker build -t todo/backend ."
                }
            }
        }

        stage('deploy') {
            steps {
                sh '''
                  docker run -d -p 5000:5000 todo/frontend

                  docker run -d -p 8080:8080 todo/backend
                '''
            }
        }
    }
}

 

이를 해석하면 다음과 같다.

 

최초의 agent 는 any로 설정해서 모든 작업을 커버할 수 있도록 하고, environment 에서는 우리가 git clone 을 할 때, 필요한 여러 정보들을 위해 정의해줬다.

 

Init 단계에서는 기존에 docker 가 띄워져 있다면 모든 도커를 꺼준다.

 

그리고 Frontend Dockerizing 이라는 stage 에서 clone 한 디렉토리에 위치한 Dockerfile 들을 이용해 Docker build 를 수행한다.

 

그 다음 Backend Dockerizing 이라는 stage 에서는 우리가 clone 한 spring boot project 를 build 하는데, 빌드에 성공하면 dockerizing 을 수행한다.

 

그리고 deploy 라는 stage 에서 우리의 도커 이미지들을 각각의 port 에 맞게 포워딩 한 후 run 명령어를 통해서 실행을 하게 된다.

 

해당 내용을 저장하고 나와서 Build Now 를 클릭하자!

 

 

그럼 다음과 같이 Build에 성공하고 우리가 Pipeline 에 명시해놓은 과정을 수행하여 성공적으로 Job을 실행하였다.

 

 

이제 마지막으로 테스트를 수행해보자!

 

2. 테스트

 

우리가 사전에 준비해놓은 Nginx를 통해서 EC2 의 80 포트로 접속하면 5000포트의 도커로 접속하게 되어서 아래의 프론트엔드 서비스가 잘 나오는 것을 알 수 있다.

 

 

하지만 문제가 있다!

 

우리가 프론트엔드에 접속하면 지난 시간 미리 만들어 놓은 import.sql 에 있는 데이터를 백엔드로부터 받아와야 한다

 

하지만 보이는것 처럼 받아오지 않는다.

 

현재 프론트엔드가 API 호출을 보내는 곳을 확인해보자

 

 

현재 프론트엔드는 127.0.0.1 의 api/todos로 요청을 보낸다.

 

우리는 테스트 환경인 Local 에서나 127.0.0.1로 명시했지, 실 서비스가 운영중인 서버의 Backend로 요청을 보내야 한다.

 

이 문제를 CICD 파이프라인을 통해서 해결해보자!!

 

frontend 디렉토리로 이동해서 SERVER.js 에 있는 API 호출 스펙을 우리가 만든 EC2 인스턴스의 IP로 변경해주자

 

import axios from "axios";

export const SERVER = axios.create({
  baseURL: "http://3.38.95.48",
  headers: {
    "Content-Type": "application/json",
  },
});

 

파일을 저장하고 github로 code push를 한다면 우리가 이전에 작성해놓은 webhookspipeline script에 의해서 새로운 버전이 즉시 배포될 것이다!

 

 

쨘~

댓글0