기존에는 EC2에 git clone 받고 jar 파일을 만든 뒤 실행시키는 과정을 스크립트로 만들어 실행하는 방법으로 배포를 했다.
하지만 이번에는 Jenkins를 이용한 자동 배포를 시도했고 나름 성공적으로 끝냈기에 이 포스트를 작성한다.
큰 순서는 다음과 같다.
1. Jenkins 서버 가동 및 세팅
2. Jenkins 내 Credential 및 Git, EC2 설정
3. Freestyle project 설정 후 설정
우선 Jenkins는 배포를 위해 이용하는 EC2와 별도의 서버로 운영된다.
나는 네이버 클라우드를 사용해서 Jenkins를 구동시켰다.
(현재 신규 가입 회원에게 10만 크레딧을 주는 이벤트를 진행하고 있기 때문에 부담 없이 사용할 수 있었다.)
네이버 클라우드에서 Jenkins 서버를 만드는 과정은 공식홈페이지 링크를 참조하자.
https://www.ncloud.com/guideCenter/guide/9
NAVER CLOUD PLATFORM
cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification
www.ncloud.com
서버 타입을 선택하는 화면에서 기본으로 선택된 타입은 월 85000원이라는 비싼 성능이다.
cpu 1개, 메모리 2GB짜리를 선택하자. 23년 12월 기준 월 4만원을 넘지 않는다.
설치하면서 다음 블로그 글을 참고했는데
https://1-7171771.tistory.com/149
[CI/CD] Jenkins를 이용해 CI/CD 자동화하기 - CI편
해당 프로젝트는 gradle6.3과 java11로 구성되어 있습니다. 프로젝트의 전체 소스 코드는 이곳에서 확인하실 수 있습니다. f-lab-edu/shoe-auction 개인 간 신발 거래 서비스. Contribute to f-lab-edu/shoe-auction dev
1-7171771.tistory.com
시기가 달라서 그런지 플러그인 설치하는 과정에서 문제가 발생하지 않았다.
JDK도 이번 프로젝에서 사용했던 Java 11이 깔려있었기 때문에 별도로 수정할 필요가 없었다.
echo $JAVA_HOME 를 실행해서 제대로 환경변수가 잡혀있는지 체크해보자!
CentosOS에 현재 사용하는 gradle과 동일한 버전을 사용해야 한다.
현재 사용하는 gradle 버전은

프로젝트에 gradle 폴더에 gradle-wrapper.properties를 보고 확인할 수 있다.
Jenkins 서버에서 다음 명령어를 입력하여 gradle을 설치해보자
wget https://services.gradle.org/distributions/gradle-8.4-bin.zip -P /tmp
다운로드 완료 후 아래 커맨드를 입력해서 /opt/gradle/ 디렉토리에서 다운받은 zip 파일 압축을 해제한다.
sudo unzip -d /opt/gradle /tmp/gradle-*.zip
ls /opt/gradle/gradle-8.4 로 설치가 되었는지 확인해보자.
그 후 아래 커맨드를 입력해 환경변수를 설정해준다.
export PATH=$PATH:/opt/gradle/gradle-8.4/bin
이제 Jenkins에서 Credentials를 만들고 Git과 연동하는 과정을 진행한다.
방금까지 참고 했던 글에서는 token을 이용했지만 현재 나는 Git에서 SSH key를 사용하고 있다.
따라서 다른 방법으로 Credentials를 등록한다.

Jenkins 관리에서 Credentials 클릭 → System 클릭 → Global credentials(unrestricted) 클릭 → Add Credentials 클릭

Kind : SSH Username with private key로 변경
ID : 자유롭게 설정. 나는 프로젝트 이름으로 설정함
Username : 자유롭게 설정. 나는 Github ID로 설정
private Key : Enter directly 클릭 후 Add 클릭
Git에서 사용하는 pem 파일을 메모장으로 열면
-----BEGIN OPENSSH PRIVATE KEY-----
-----END OPENSSH PRIVATE KEY-----
로 되어있는 내용이 나온다. 전체 다 (BEGIN 있는 줄과 END 있는 줄도 포함) 복사해서 해당 부분에 붙여넣는다.
그리고 Create!!
다음은 Gradle 설정이다.

Jenkins 관리에서 Tools 클릭
Gradle installations 에서 Add Gradle 클릭

name : 젠킨스 내에서 사용할 이름 설정
나는 install automatically를 체크하고 Version에서 내가 사용하는 Gradle과 같은 버전을 찾았지만
저 부분을 체크 해제할 경우 직접 GRADLE_HOME을 작성해야 한다.
아까 입력했던 환경 변수의 경로와 같이 입력하면 된다. (/opt/gradle/gradle-8.4)
이렇게 하고 저장!
현재 Jenkins를 사용하는 목표는 Push 가 동작했을 때 자동으로 배포가 되도록 만들기 위한 것이다.
따라서 먼저 Github에서 Webhook 설정을 하도록 한다.

프로젝트 Github의 Setting에 들어가면 Webhook이 있다. Add webhook을 클릭한다.

Payload URL : http://젠킨스 서버의 ip:젠킨스 포트(18080)/github-webhook/
Content type : application/json
밑에서는 Just the push event 를 클릭한다.
push가 발생 시 hook이 유발된다.
Add webhook을 클릭하여 생성한다.
다음으로는 Jar 파일을 EC2에 배포할 때 사용할 Publish Over SSH 플러그인을 설치한다.
Jenkins 관리에서 Plugins를 들어간다.
installed plugins에서 혹시 기존에 설치했는지 확인해보고 설치가 되어있지 않다면 Available plugins에서 해당 플러그인을 검색하여 설치하자.
설치 후 Jenkins 관리에서 System에 들어가면 Publish over SSH가 있는 것을 알 수 있다.

해당 부분 Key항목에 EC2 인스턴스 생성 시 발급받은 pem 파일 내용을 복사 붙여넣기 한다.
(마찬가지로 BEGIN 있는 줄부터 END 있는 줄까지 전부 복사해서 붙여넣는다.)
그 밑에 SSH 서버의 빈칸을 작성한다.

Name : 본인이 사용할 임의의 SSH Server의 Name을 입력한다.
Hostname: 실제로 접속할 원격 서버 ip를 입력한다. (EC2에서 사용하는 퍼블릭 IPv4 주소를 넣으면 된다.)
Username: 접속할 원격 서버의 user 이름. (나는 ubuntu로 설정했다.)
Remote Directory : 원격서버에서 접속하여 작업을 하게 되는 디렉토리(/home/ubuntu로 설정했다.)
Test Configuration을 눌러서 Success 문구가 나오면 된다.
이제 프로젝트를 생성한다.
Jenkins 메인 페이지에서 새로운 Item을 클릭한다.
Freestyle project로 생성한다.

GitHub project를 클릭하고 프로젝트 URL를 입력하자.
(.git을 제거해야 한다는 말도 있었는데 붙여서 시도했을 때 문제 없었다.)

소스 코드 관리에서 Git을 선택한다.
Repository URL: 프로젝트 URL을 입력하자.
Credentials : 전에 만들어둔 credential을 선택할 수 있다. 선택하자!
Branch: 어떤 브랜치에서 빌드를 수행할 지 지정하는 옵션

빌드 유발에서 Github hook trigger for GITScm polling을 선택한다. Webhook을 설정했기에 hook이 발생하면 빌드에 들어간다.

Build Steps 부분에서 Invoke Gradle script를 선택한다.
Gradle Version에서 설정해놓은 버전을 선택한다.
Tasks에서 clean build를 입력한다.
(현재 test 부분에 문제가 생겨 build가 이루어지지 않아서 test 부분을 제외하기 위해 -x test를 입력했다.)

Name : 자유롭게 작성
Source files : 전송할 파일의 위치를 적는다.
Jenkins의 workspace 기준으로 build/libs 하위에 jar 파일이 생성되기에 build/libs/*.jar를 작성한다.
Remote Directory : 파일을 전송할 원격 서버의 디렉토리를 명시한다. SSH 서버 설정 부분에서 경로(/home/ubuntu)를 적었기 때문에 그 이후 경로를 작성하면 된다. 나는 /home/ubuntu/app/usports 라는 경로에 jar파일을 가져다 놓을 것이기에 이렇게 작성했다.
Exex command : 파일 전송 후 실행할 명령어를 입력한다. 절대 경로로 작성했다.
(Name 에 있는 고급 버튼을 누르면 나오는 항목 중 Verbose output in console을 체크하면 빌드할 때 상세 내역이 표시되므로 유용하다.)
Exex command에서 파일 전송 후 start_server.sh를 실행시키는 명령어를 입력했다.
따라서 start_server.sh를 작성해서 배포 과정이 진행될 수 있도록 하자.
#!/bin/bash
REPOSITORY=/home/ubuntu/app/usports
PROJECT_NAME=USports_BE
JA_NAME=Usports
echo "> 현재 구동 중인 애플리케이션 pid 확인"
CURRENT_PID=$(ps -ef | grep java | grep USports | awk '{print $2}')
echo " 현재 구동 중인 애플리케이션 pid: $CURRENT_PID"
if [ -z "$CURRENT_PID" ]; then
echo "> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않는다."
else
echo ">kill -15 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi
echo "> 새 애플리케이션 배포"
JAR_NAME=$(ls -tr $REPOSITORY/ | grep jar | tail -n 1)
echo "> JAR Name: $JAR_NAME"
sudo nohup java -jar \
-Dspring.config.location=classpath:/application.properties,/home/ubuntu/app/usports/USports_BE/application-private.properties \
$REPOSITORY/$JAR_NAME > /dev/null 2>&1 &
현재 애플리케이션이 구동중이면 Kill 하고 전송 받은 Jar 파일을 실행하는 스크립트이다.
Jenkins에서 build를 진행시켜서 제대로 작동하는지 확인해보자!
참고 :
https://velog.io/@sa1341/Jenkins%EC%97%90%EC%84%9C-EC2%EB%A1%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0
Jenkins에서 EC2로 배포하기
GitHub와 젠킨스를 SSH로 연동했다면, 이제 AWS(Amazone Web Service)에서 제공하는 가장 유명한 EC2(Elastic Compute Cloud)에 배포를 해봤습니다.먼저, Jenkins에서 제공해주는 플러그인 중에 SSH로 EC2에 jar 배포
velog.io
시리즈 | [CI/CD] Jenkins로 배포 자동화하기 - qudalsrnt3x.log
Github Webhook을 이용한 자동 빌드 환경 구축 2021년 6월 9일
velog.io
[Jenkins] Git Repository와 Jenkins 연동 (2) : Jenkins SSH Key 설정
↓↓ SSH Key 발급 및 git 설정 방법 ↓ ↓ https://chati.tistory.com/24 [Jenkins] Git Repository와 Jenkins 연동 (1) : SSH Key 생성 및 Git 설정 ↓↓ SSH Key 발급 및 git 설정 완료 후 Jenkins 설정 방법 ↓ ↓ https://chati.tist
chati.tistory.com
https://1-7171771.tistory.com/149
[CI/CD] Jenkins를 이용해 CI/CD 자동화하기 - CI편
해당 프로젝트는 gradle6.3과 java11로 구성되어 있습니다. 프로젝트의 전체 소스 코드는 이곳에서 확인하실 수 있습니다. f-lab-edu/shoe-auction 개인 간 신발 거래 서비스. Contribute to f-lab-edu/shoe-auction dev
1-7171771.tistory.com
원래 목적이 특정 브랜치에 merge 될 때 배포가 되도록 하려는 것이여서 이런 방식으로 가능했지만
찾아보니 PipeLine 등 이것저것 공부해야 할 것들이 많은 것 같다. 브랜치 별로 관리하는 법도 있는 것 같다.
조금 더 알아보고 실습 후에 추가적으로 정리하고자 한다.
'개발 지식 기록 > 프로젝트~' 카테고리의 다른 글
Amazon EC2 인스턴스 생성 (0) | 2024.01.13 |
---|---|
Jenkins 사용기(Pipeline) (0) | 2024.01.12 |