[Jenkins] 4. Build 성공 후 앱 자동 배포하기

2020. 8. 19. 12:14CentOS 7/Jenkins

300x250
반응형
  1. Post build task 플러그인 설치
  2. 빌드 후 조치 - Post build task 설정 추가 (기본)
    2-1) 빌드 실패시 콘솔 출력 결과
    2-2) 빌드 성공시 콘솔 출력 결과
  3. demo 앱 배포 후 재시작

이전 시간에서 GitHub의 push 이벤트 발생시 GitHub Hook을 발생시켜 demo 앱을 자동으로 빌드하는 것 까지 알아봤습니다.

빌드를 자동으로 처리했다면, 이제 기존에 서비스 중이었던 앱을 종료시키고 새 앱을 실행시키는 부분을 알아봐야겠죠?

기존에 서비스 중이었던 앱을 새로 빌드한 앱으로 교체하여 실행시키려면 어떻게 해야할까요?

  1. 서비스중인 앱을 종료
  2. 백업 폴더 비우기
  3. 백업 폴더에 기존 앱을 복사(기존 서비스 앱 백업하기)
  4. deploy된 최신 빌드 앱을 복사
  5. 앱 실행

간단하게 위와 같은 처리가 필요할 것입니다.
기존 앱을 백업할 필요가 없다면 2, 3번 대신 기존 앱을 삭제하는 과정을 거치면 됩니다.

그럼, 본격적으로 새로 빌드된 앱으로 서비스를 재실행하는 과정을 진행해봅시다.


1. Post build task 플러그인 설치

maven 을 이용하여 spring boot 앱을 build 했을 때, 빌드가 성공했을 시, BUILD SUCCESS라는 메시지를 로그상에 출력합니다.

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.454 s
[INFO] Finished at: 2020-08-14T17:13:25+09:00
[INFO] ------------------------------------------------------------------------

빌드가 성공했을 경우에만, 후 조치로 기존 앱을 종료시키고 새로운 앱으로 교체 및 시작하는 과정을 진행하기 위해 Post build task 플러그인을 설치합니다.

45

Jenkins 관리 → 플러그인 관리


2. 빌드 후 조치 - Post build task 설정 추가 (기본)

46

빌드 후 조치 탭에서 Post build task 를 추가해봅니다.

47

그러면 위와 같은 상자가 추가됩니다.
Tasks에는 빌드 완료 후 취할 행동들을 작성하면 되는데

Log 상에 출력된 메시지를 통해 빌드가 성공했을 경우에만 script를 실행시키도록 합니다.

Log text, Operation 박스는 여러개 설정할 수 있기 때문에 OR 조건으로 설정한 조건중 하나만 만족하더라도 Script를 실행시키도록 할 수도 있고. 또는 AND 조건을 이용하여 여러 조건을 만족했을 시에만 Script를 실행하도록 할 수 있습니다.

Exception 별로 별도의 처리를 하고 싶다면 task를 추가하면 됩니다.

저는 간단히, Maven Build 성공/실패시 출력되는 BUILD SUCCESSBUILD FAILURE 메시지의 콘솔 출력 여부에 따라 별도의 Script를 실행하도록 할 것입니다.

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.071 s
[INFO] Finished at: 2020-08-19T09:50:50+09:00
[INFO] Final Memory: 43M/277M
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 34.872 s
[INFO] Finished at: 2020-08-19T10:18:33+09:00
[INFO] Final Memory: 47M/360M
[INFO] ------------------------------------------------------------------------

빌드 성공, 실패에 대한 task를 추가해봅시다.

49

빌드 성공 및 실패시에 대한 task 실행 결과를 확인해보기 위해 database server 의 접속정보를 변경한 후 빌드를 진행해 보았습니다.

2-1) 빌드 실패시 콘솔 출력 결과

Match found for :SQLNonTransientConnectionException : True
Match found for :BUILD FAILURE : True
Logical operation result is TRUE
Running script  : echo "Build 중 에러 발생"

[test] $ /bin/sh -xe /tmp/jenkins3871056391086027804.sh
+ echo 'Build 중 에러 발생'
Build 중 에러 발생
POST BUILD TASK : SUCCESS
END OF POST BUILD TASK : 0
Could not match :BUILD SUCCESS  : False
Logical operation result is FALSE
Skipping script  : echo "Build 성공"
END OF POST BUILD TASK : 1

datasource 접속정보 불일치 문제로 maven test 중 에러가 발생했을 때의 jenkins 콘솔 출력 정보입니다.
SQLNonTransientConnectionException, BUILD FAILURE 로그 텍스트가 조회되었기 때문에 echo "Build 중 에러 발생" Script가 실행됩니다.

BUILD SUCCESS 로그 텍스트가 조회되지 않기 때문에 echo "Build 성공" Script는 실행되지 않습니다.

2-2) 빌드 성공시 콘솔 출력 결과

Could not match :SQLNonTransientConnectionException  : False
Could not match :BUILD FAILURE  : False
Logical operation result is FALSE
Skipping script  : echo "Build 중 에러 발생"

END OF POST BUILD TASK 	: 0
Match found for :BUILD SUCCESS : True
Logical operation result is TRUE
Running script  : echo "Build 성공"
[test] $ /bin/sh -xe /tmp/jenkins4029007285557942681.sh
+ echo 'Build 성공'
Build 성공
POST BUILD TASK : SUCCESS
END OF POST BUILD TASK : 1

에러없이 정상적으로 maven 테스트 및 빌드를 마쳤을 때의 jenkins 로그 출력 결과입니다.
SQLNonTransientConnectionException, BUILD FAILURE 로그 텍스트가 조회되지 않았고, BUILD SUCCESS 로그 텍스트가 조회되었습니다.


3. demo 앱 배포 후 재시작

이제 기존에 서비스 중이었던 앱을 새로 빌드한 앱으로 교체하여 재실행시키는 Script를 작성해보도록 합시다

JENKINS_HOME=/var/lib/jenkins

jenkins 홈디렉토리를 JENKINS_HOME에 설정합니다.

50

참고로, 저는 JENKINS_HOME 디렉토리 내에 deploys 디렉토리를 만들어, jenkins에서 생성한 item들의 배포판을 위치시킬 것입니다.

  • demo.jar : demo 웹 애플리케이션
  • backup : 이전버전 demo 앱의 백업 파일이 들어갈 백업 디렉토리
  • logs : 로그파일이 저장될 디렉토리
  • work : embedded Tomcat 임시파일 저장위치

work 디렉토리는 server.tomcat.basedir를 demo 앱이 위치한 장소로 설정을 했기 때문에 demo앱실행시 자동으로 생성되는 디렉토리입니다.
별도로 basedir 디렉토리를 설정하지 않을 경우에는 /tmp에 임시 파일들이 생성됩니다.


pid=$(ps -eaf | grep demo.jar | grep -v "grep" | awk '{print $2}')

if [ "$pid" == "" ]; then
    echo "demo web application is not running."
else
    kill -9 $pid
    echo "demo web application process killed forcefully. (pid : $pid)"
fi

demo.jar 웹 애플리케이션이 ps(프로세스 상태 조회) 명령어로 조회하여 현재 실행중인지 체크합니다.
그 중, grep 문자열이 들어간 프로세스는 제외시킵니다(검색을 위해 이용된 프로세스입니다.)
마지막으로, awk명령어를 이용하여 2번째 필드값만 pid 변수에 넣습니다.

만일 pid가 빈문자열이라면 실행중인 demo.jar 앱이 없었던 것이고, 있다면 해당 프로세스를 종료시킵니다.

cd $JENKINS_HOME
if [ ! -d $JENKINS_HOME/deploys ]; then
    mkdir deploys
    echo "The deploys directory was created successfully."
fi
cd ./deploys

if [ ! -d demo ]; then
    mkdir demo
    echo "The demo directory was created successfully."
fi
cd ./demo

배포를 위해 필요한 디렉토리를 생성합니다.
if [! -d 디렉토리명]; 을 이용하여 디렉토리 존재유무를 확인할 수 있습니다.
만일 디렉토리가 없다면 디렉토리를 생성해줍니다.

rm -rf ./backup/*
if [ ! -d backup ]; then
    mkdir backup
    echo "The backup directory was created successfully."
fi

if [ -e demo.jar ]; then
    mv demo.jar backup/
    echo "backup was successful."
fi

backup 디렉토리에 이전버전의 demo 애플리케이션을 백업하기 전에 기존에 들어있던 파일들을 제거합니다.
마찬가지로, backup 디렉토리가 없다면 새로 생성해줍니다.

cp $JENKINS_HOME/workspace/demo/target/demo.jar demo.jar
nohup  java -jar demo.jar 2>> /dev/null >> /dev/null &

새로 빌드된 demo앱을 배포 디렉토리 내에 복사한 후,
nohup 명령어와 & 명령어를 이용하여 background 상에 demo앱을 실행시킵니다.

참고로 jenkins는 빌드 과정을 모두 마친 후, jenkins 사용자로 실행된 child process를 모두 kill 시키기 때문에 nohup로 실행시킨 demo앱이 종료되는 현상이 발생됩니다.

이를 방지하기 위해 Script의 맨 위에 BUILD_ID=dontKillMe 변수를 설정해둡니다.

export BUILD_ID=dontKillMe

51

완성된 Script 최종 모습입니다.

300x250
반응형