Jenkins로 Spring Boot 2 + Vue 3 프로젝트를 리눅스 서버에 배포하기 (3)

새로운 빌드 Item 생성하기

Jenkins 메인 화면 좌측에 새로운 Item 이라는 버튼을 클릭하자.

Item을 식별할 이름을 지정 해준 뒤, Freestyle project를 선택하고 OK 버튼을 클릭한다. 나는 Book Management App 이라는 이름으로 지정해 주었다.


가장 위, 설명에 이 Item이 어떤 것인지 알려주는 문구를 적어주자. (EX. 이 Item은 나의 프로젝트를 빌드하는 Item 입니다.)

만약 GitHub 프로젝트를 Clone해서 빌드하고 있다면, GitHub project 체크 박스에 체크하고 해당 리포지토리의 정보를 추가로 적어주면 된다.


다음은 소스 코드 관리를 설정해야 한다. 나는 Git을 사용하기 때문에 항목에서 Git을 선택했다. (Mercurial이나 SVN은 추가로 플러그인을 설치해야 한다.)

각 항목을 채워준다.

  • Repository URL: Clone할 프로젝트 리포지토리의 URL
  • Credentials: 해당 리포지토리에 접근 가능한 Git 계정
  • Branch Specifier: Clone할 브랜치 명

Credentials에 채워 넣을 계정이 없다면 새로 하나 추가하기 위해 Credentials 항목의 + Add 버튼을 클릭하고 Jenkins를 클릭하자.

Git ID를 Username에 패스워드는 Password에 입력하고, 계정을 식별하기 위한 Description을 채우고 Add 버튼을 클릭한다.

💡
GitHub는 2021년부터 리포지토리에 접근 할 때, 계정의 패스워드가 아닌 Access Token을 이용해 접근하도록 정책이 바뀌었다. 따라서, GitHub를 이용해 소스 코드를 관리하는 경우에는 발급 받은 Access Token 값을 Password칸에 입력해야 한다.

다음은 빌드 유발 항목을 설정해야 한다. 일반적으로 GitHub 웹 훅을 이용해 push가 일어날 때마다 자동으로 빌드를 시도하도록 자동화 하는 경우가 많다. 하지만 나 같은 경우에는 Jenkins 서버를 외부에 노출 시키기 싫기도 하고 상당히 자주 commit/push 하는 까닭에 그냥 일정 시간마다 빌드를 시도하도록 설정했다. 먼저 빌드 유발 항목에서 Build periodically 체크 박스를 체크하자.

그리고 3시간 마다 빌드가 되도록 'H */3 * * *' 이라고 적는다. 이런 표현 방법을 cron expressions(크론 표현식) 이라고 한다.

cron expressions에 대해 궁금하다면 아래의 글을 참조하도록 하자.

크론 표현식(Cron Expressions)
크론 스케쥴러(Cron Scheduler)에 사용하는 크론 표현식(Cron Expressions에 대해서 알아보자

다음은 Build 항목에서 Spring Boot 2 프로젝트와 Vue 3 프로젝트를 빌드 되도록 설정해야 한다. 먼저 Vue 3 프로젝트부터 빌드 되도록 설정하겠다. Add build step 드롭 박스를 클릭하고 Execute NodeJS script를 선택한다.

NodeJS Installation 항목에서 이전 글에서 추가한 NodeJS 버전을 선택한다.

Add build step 드롭 박스를 다시 클릭하고, 이번에는 Execute shell을 선택한다.

추가 된 항목에서 Command 칸에 Vue 3 프로젝트를 빌드 하는 명령어를 입력해준다. 프로젝트를 빌드하는 명령어는 개발자의 프로젝트 설정에 따라 상이 할 수 있기 때문에, 여기서는 나의 프로젝트를 빌드 하는 명령어를 사용했다.

cd "/var/jenkins_home/workspace/Book Management App/src/frontend"
yarn install
yarn clean
yarn build
내 프로젝트를 빌드하는 명령어

모두 채우고 나면 아래와 같아질 것이다.

Add build step 드롭 박스를 클릭하고 이번에는 Invoke Gradle script를 선택한다.

그 다음, 이전 글에서 추가한 Gradle 버전을 선택하고 Tasks 항목 오른쪽의 확장 버튼을 클릭한다.

Vue 3 프로젝트 빌드와 마찬가지로 Spring Boot 2 프로젝트도 빌드 명령어는 개발자의 설정에 따라 상이할 수 있다. 설정에 맞춰 Tasks 항목에 빌드 명령어를 채우도록 하자. 참고로 --exclude-task test 옵션은 test 과정을 건너뛰는 옵션이다.

clean
-PisProd=true build --exclude-task test
앞에 gradle을 붙이면 안된다

마지막으로 Publish over SSH 플러그인을 이용해 배포하는 작업을 해주어야 한다. 마찬가지로 Add build step 드롭 박스를 클릭해서 Send files or execute commands over SSH를 클릭한다. Vue 3, Spring Boot 2 프로젝트 두 개를 배포해야 하기 때문에 두 번 추가하도록 하자.

Send files or execute commands over SSH 항목이 뜨면 다음의 4개 항목을 채우도록 하자

  • Source files: 빌드가 완료된 파일들의 위치
  • Remove prefix: 파일 경로에서 삭제하고 싶은 문자열
  • Remote directory: 배포하고자 하는 배포 서버의 경로
  • Exec command: 배포 후 실행할 명령어
Vue 3 프로젝트 배포

Vue 3 프로젝트는 Book Management App 디렉토리를 기준으로 Souce files이 src/frontend/dis/spa 디렉토리에 빌드 결과물이 저장된다. **는 해당 디렉토리의 모든 파일을 의미한다. 모든 파일의 경로에는 앞에 src/frontend/dis/spa가 붙기 때문에 이것을 제거하기 위해 Remove prefix에 src/frontend/dis/spa 문자열을 지정해준다. 이 파일들을 원격 서버의 /home/ubuntu/data/nginx/html에 배포하기 위해 Remote directory에 data/nginx/html 문자열을 지정해준다.

💡
/home/ubuntu 경로는 이전 글에서 Publish over SSH를 설정할 때, Remote directory로 /home/ubuntu를 지정해 줬기 때문에 적지 않아도 상관없다.
jar 파일 명이 잘못 캡쳐되어서 모자이크 처리했다(...)

위의 Vue 3 프로젝트 배포를 바탕으로 Spring Boot 2 프로젝트도 배포해보자. Spring Boot 2 프로젝트는 jar 파일 하나만 배포하면 되기 때문에
build/libs/<프로젝트 명>.jar를 직접 Source files에 지정해주면 된다. 마찬가지로 build/libs를 경로에서 제거하기 위해 Remove prefix에 build/libs 문자열을 지정해준다. 이 jar 파일은 원격 서버의 /home/ubuntu/repo에 배포한다. Exec command에는 다음과 같은 명령어를 입력해준다.

CURRENT_PID=$(ps -ef | grep java | grep <프로젝트 명>* | awk '{print $2}')

if "$CURRENT_PID" [ -z CURRENT_PID ] ; then
    echo "Not running"
else
    kill -15 $CURRENT_PID
    sleep 10
fi

echo "Deploy..."

nohup java -jar /home/ubuntu/repo/bookmanagement.jar >> /home/ubuntu/logs/bookmanagement.log 2>&1 &
현재 실행 중인 <프로젝트 명>.jar 프로세스를 종료하고 새로운 프로세스를 실행하는 명령어다
💡
다른 글을 보면 kill -9를 사용하는 경우도 있다. -9는 종료 시 에러가 발생하더라도 강제로 프로세스 종료 하고 -15는 안전하게 프로세스를 종료하는 옵션이다. 개발 서버는 -9 옵션을 써도 상관 없으나, 실제 서비스 환경에서는 -15 옵션을 쓰는 게 좋다.

모든 설정이 완료 된다면 가장 밑에 있는 Apply, 저장 버튼을 순서대로 누르고 완료하도록 하자.


이제 Jenkins 홈으로 돌아와 빌드 테스트를 해보도록 하자. 새로 추가했던 Item인 Book Management App을 클릭하자.

Book Management App을 클릭하고 들어온 화면 좌측에 지금 빌드 버튼을 클릭하면, 아래에 Build History 쪽에 새로운 작업이 추가 되면서 현재의 빌드 진행도를 보여준다. 만약 정상적으로 빌드가 완료되면 초록색 체크 표시가 뜨게 될 것이다.

#33인 이유는 테스트 하느라 32번이나 실패했기 때문이다(...)

정리하며

정말로 긴 과정을 거쳐 자신의 프로젝트를 자동으로 배포하는 데에 성공했다. 이렇게 힘든 과정을 거치면서 자동화를 할 필요가 있을지 의문을 가지는 사람이 있을지도 모른다. 하지만 이런 배포 자동화의 대가는 엄청나게 가치가 있을 것이다. 이렇게 자동화를 하면 개발자는 더 이상 배포에 신경 쓰지 않아도 개발에만 집중 할 수 있기 때문이다. 다음에는 Sornar Cube와 JUnit 테스트를 자동화 하는 방법에 대해서도 연구해 볼 예정이다.


참고한 문헌 및 블로그 글

  1. [Jenkins] Jenkins - Spring Boot 프로젝트 jar 배포