[CI/CD] SpringBoot 프로젝트 .jar 파일 빌드 및 배포 자동화

dooboocookie·2022년 10월 25일
1

목표

문제

  • 지난번 EC2 배포(링크) 이후, 배포 후 변경 점을 서버에 적용하기 위해서 이미 .jar파일 실행을 종료하고 파일 변경 후 다시 실행시켜야한다는 번거로움이 있었다.
  • 그래서, CI/CD를 적용하기로 했다.
  • 현재 우리의 프로젝트는 상당히 가볍고 심플한 단계이므로 하나의 EC2안에서 젠킨스와 .jar을 둘 다 실행시킬 예정이다.

목표 과정

  1. SpringBoot 프로젝트에서 변경 후 GitHub 레포에 push
  2. EC2에서 해당 변경을 인지하여 clone
  3. 해당 SpringBoot 프로젝트 build
  4. 빌드된 .jar 파일을 실행

Jenkins 설치 및 설정

  • Jenkins는 JVM환경에서 돌아가는 CI/CD 툴이다.
  • 프로젝트의 소스의 통합과 테스트 및 빌드, 배포를 위해 사용

EC2에 Jenkins 설치

  • 지난번 과정에서 EC2에 JDK는 설치하였으므로 JDK설치는 생략
  • apt 업데이트
apt-get update
  • Jenkins Repository에서 Key 받아오기
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
  • sources.list에 Jenkins.list 추가
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > \
    /etc/apt/sources.list.d/jenkins.list'
  • Jenkins 설치
sudo apt-get install jenkins
  • Jenkins 실행 관련
# 실행
sudo systemctl start jenkins
# 종료
sudo systemctl stop jenkins
# 재시작
sudo systemctl restart jenkins
# 상태 체크
sudo systemctl status jenkins
  • 상태 체크 시, 아래와 같이 확인되면 잘 실행된 것

  • 기본적으로 Jenkins를 처음 설치하면 8080포트가 기본으로 설정되어 있는데, 필요하다면 포트 변경이 필요하다
sudo vi /etc/default/jenkins
  • vim 에디터를 켜서 포트 설정을 원하는 포트번호로 변경해준다
    • vim 에디터 INSERT는 i 입력
    • INSERT 나올 떄는 esc 입력
    • 저장 후 종료는 :wq! 입력

  • 위와 같이 설정하고 재시작을 해도 여전히 8080포트로 설정되어있을 경우에는
  • jenkins.service 파일에 JENKINS_PORT 환경변수를 변경해줘야한다.
  • jenkins 상태체크 시 확인된 jenkins.service 파일의 위치를 vim 에디터로 실행 후 JENKINS_PORT 변경
sudo vi /lib/systemd/system/jenkins.service

  • 포트 변경 완료 후, Jenkins 재시작
  • 변경된 포트의 EC2 인바운드 규칙이나 방화벽 설정도 필요하다면 해줘야한다.

Jenkins 설정

  • http://{EC2의 퍼블릭 IPv4 주소}:{설정한 포트번호} 에 접속하면 초기 비밀번호 화면이 나온다.

  • 비밀번호 위치에 있는 비밀번호를 확인하여 Administrator password에 입력
sudo cat /var/lib/jenkins/secrets/initialAdminPassword 
  • Install suggested plugins을 눌러 추천 플러그인을 설치
  • 로그인 정보를 입력한다.
    • 이 로그인 정보는 이 젠킨스를 접속할 떄 사용할 것이므로, 잊어버리면 안된다.
  • 여기까지 되면, Jenkins를 사용할 준비 완료!

Jenkins에 GitHub 연동 및 설정

  • GitHub의 토큰은 이미 발급받았다고 판단하고 진행

GitHub Token 등록

  • Jenkins 관리Manage CredentialsSystemGlobal credentialsAdd Credentials

  • Username : GitHub ID
  • Password : GitHub Token
  • ID : 해당 Credentia 이름

GitHub Server 등록

  • Jenkins 관리시스템 설정GitHub ServersAdd GitHub Server

  • Add 버튼을 눌러
    • Kind : Secret Text 선택
    • Scret : GitHub token
    • ID : 이 Credentials의 이름
  • Name 설정 후 Test connection으로 연결 확인 후 저장

GitHub webhook 등록

  • 등록하고자 하는 GitHub Repository 접속
    • Settings → Webhooks → Add webhook

  • PayloadURL : https://{젠킨스 hostIP}:{포트번호}/github-webhook/
  • Content type : application/json으로 설정 후
  • Add webhook

SpringBoot 프로젝트 빌드 및 배포

Gradle 설정

  • 해당 프로젝트를 그래들로 빌드할 것이므로 그래들 설정을 해준다
  • 플러그인 설치
    • Jenkins 관리 → 플러그인 관리 → 설치가능 탭 → 필터 검색
    • Gradle Plugin : 프로젝트를 Gradle로 빌드할 수 있는 플러그인
    • Post build task : 빌드 로그를 판단해 batch/shell을 실행하는 플러그인

  • Jenkins 관리 → Global Tool Configuration → Gradle → Add Gradle
    • 맞는 Gradle 버전을 설정

프로젝트 추가

  • 대시보드에서 + 새로운 Item 클릭
  • 현재는 아주 간단한 작업을 수행할 것이므로, Freestyle project를 만
    들 것이다

1. 소스코드 관리

  • Git으로 설정
    • 연동하고자 하는 GitHub Repository URL 입력
    • Credentials 은 이전에 등록했던 깃헙 아이디와 토큰을 가지고 있는 것을 선택

2. 빌드 유발

  • GitHub Repo에 push하면 웹훅이 해당 젠킨스로 내용 전달해주는 것을 트리거로 빌드할 수 있도록 하는 설정
    • GitHub hook trigger for GITScm polling 활성화

3. 빌드

  • Gradle로 빌드 할 것이므로 Invoke Gradle script로 추가
  • Gradle Version은 위에서 설정한 Gradle로 설정
  • bootJar : 즉, Gradle이 SpringBoot 빌드하는 명령

4. 빌드 후 조치

  • 이제 push → clone 후 build 까지는 완료 되었으니, 이미 실행 중인 프로젝트를 종료하고, 해당 빌드된 .jar파일을 실행시켜야한다.
  • Log text : BUILD SUCCESS
  • Script : 이미 실행중인 프로젝트 종료하는 스크립트와 실행시키는 스크립트
# 8080포트에서 실행 중인 프로세스를 KILL 하는 명령어
fuser -k -n tcp 8080

# 해당 .jar 파일을 백그라운드에서 자바로 실행시키는 명령어
nohup java -jar /var/lib/jenkins/workspace/{현재 만들고 있는 프로젝트명}/build/libs/{빌드된 .jar파일명} &
  • /var/lib/jenkins/workspace/{현재 만들고 있는 프로젝트명} 이 디렉토리는 현재 만들고 있는 젠킨스 프로젝트를 만들면 만들어질 것이다.

  • /var/lib/jenkins/workspace/{현재 만들고 있는 프로젝트명}/build/libs/{빌드된 .jar파일명} 이 위치의 .jar파일은 bootJar가 실행되면 만들어질 것이다.

  • 저장하면 모든 작업 끝

EC2 프리티어 환경에서의 문제점

  • EC2 프리티어 t2.micro 에서 제공하는 RAM 크기는 1GB
  • t2.micro 인스턴스에서 Jenkins를 통하여 빌드를 시키면 인스턴스가 갑자기 먹통이 된다.
  • 사양을 초과한 것이다.

해결

  • Swap을 통하여, RAM 용량이 부족할 때, SWAP공간을 사용하여 RAM보단 느리지만 추가적인 용량을 제공받는 과정이 필요하다.
  1. 루트파일에 swapfile 생성 후 권한 부여
sudo dd if=/dev/zero of=/swapfile bs=128M count=16
sudo chmod 600 /swapfile
  1. swap 영역 설정
sudo mkswap /swapfile
  1. swap 영역에 swapfile 추가 사용
sudo swapon /swapfile
  1. 확인
sudo swapon -s
  1. 부팅 시, 스왑 파일 시작할 수 있도록 vim 에디터로 수정
    • 맨 밑 줄에 /swapfile swap swap defaults 0 0추가
sudo vi /etc/fstab


6. 추가 공간 확인

sudo free

테스트

  1. 위에서 연결한 GitHub Repository와 연결된 프로젝트를 push

  1. Jenkins Project에서 확인 build 내역 확인 가능

  1. 해당 빌드 내역에서 Console Output에서 내역 확인

  1. 실행되었을 프로젝트로 접속하여 변경 점 확인

추가적으로 해결할 문제

  1. 현재 젠킨스 서버와 프로젝트 서버가 하나의 EC2다 보니 상당히 불안하다
  2. 우리 프로젝트의 application.properties는 git의 관리 대상이 아니므로, 빌드할 때 어떻게 포함시킬지 고민해봐야한다
profile
1일 1산책 1커밋

0개의 댓글