2025. 4. 16. 16:36ㆍ기술 창고/CI, CD
개발을 진행하면서 수정하거나 변경한 내용, 혹은 이때까지 만든 최신 내용을 반영하여 빌드하고 배포하여 다시 실행하는 과정까지 걸리는 시간은 절대 무시못할 시간 소요가 걸리게 됩니다.
이것을 해결하기 위해서 CI/CD를 적용하여 한 번에 효율적으로 테스트, 빌드, 배포까지 모든 처리를 한 번에 할 수 있게끔 하는데 이러한 CI/CD 작업을 일반적으로 대부분 Jenkins라고 하는 외부 툴을 사용하는 것이 일반적이라고 알고있습니다.
하지만, 어떤 최근 매체에서 읽기를, 굳이 외부 툴을 사용하는 것이 효율적이라고 볼 순 없다라는 글을 읽었으며 또한 외부 툴에 문제가 발생되었을 경우 이것을 해결하기 위한 시간 소요가 추가적으로 발생되게 됩니다.
따라서 개발을 위해 거의 반드시 사용하게 되는 Github 를 통해 이 CI/CD 작업을 수행할 수 있게 한다면 좀 더 편하고 관리하기에도 수월하지 않을까 하는 생각이 들어 Github Actions를 사용해보기로 하였습니다.
오늘은 이 Github Actions를 활용한 CI/CD 방법을 정리해보겠습니다.
(1) 배포할 서버에 프로젝트 Git Clone
우선 CI/CD 가 적용되어 배포될 서버에 들어가서 진행하고 있는 프로젝트를 clone 해줍니다.
jar 파일을 올릴 서버에 git clone {github repository 주소} 를 입력하여 클론
- username 입력 (예 : JayEsEichi)
- password 입력 (github 계정 토큰값)
## 참고사항 ##
지금 이미 CI/CD를 적용하기 이전에 작업한 내용이 남아있다면 우선 그것들을 먼저 commit, push 후 최신화 시켜주시기 바라고, 이후에 나올 yml 파일 작성 내용에 특정 브랜치에 작업을 수행하게끔 하는 부분이 있는데 될 수 있는한 해당 브랜치에도 방금 push 한 최신 내용을 지금 미리 push 해놓으시면 좋습니다.
(2) Github Actions 작업 경로 및 실행 yml 파일 생성
우선 프로젝트의 내부 최상위 경로에 .github 경로를 만들어주고, workflows 경로를 만든 뒤, Github Actions에서 실행될 yml 파일을 만들어줍니다.
(3) yml 파일 내용 작성
name: Deploy
on:
push:
branches:
- dev
jobs:
Deploy:
runs-on: ubuntu-latest
steps:
- name: CI/CD
uses: appleboy/ssh-action@v1
env:
APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
APPLICATION_DEV_PROPERTIES: ${{ secrets.APPLICATION_DEV_PROPERTIES }}
APPLICATION_PROD_PROPERTIES: ${{ secrets.APPLICATION_PROD_PROPERTIES }}
APPLICATION_YML: ${{ secrets.APPLICATION_YML }}
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER_NAME }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
envs: APPLICATION_PROPERTIES, APPLICATION_DEV_PROPERTIES, APPLICATION_PROD_PROPERTIES, APPLICATION_YML
script_stop: true
script: |
cd /home/onnury/web/Onnury-Mall-BackEnd
echo "온누리 몰 프로젝트 경로 진입"
rm -rf src/main/resources/application.properties
rm -rf src/main/resources/application-dev.properties
rm -rf src/main/resources/application-prod.properties
rm -rf src/main/resources/application.yml
echo "gitignore 처리된 이전 properties, yml 파일 삭제"
git pull origin dev
echo "dev 브랜치 pull"
echo "$APPLICATION_PROPERTIES" > src/main/resources/application.properties
echo "$APPLICATION_DEV_PROPERTIES" > src/main/resources/application-dev.properties
echo "$APPLICATION_PROD_PROPERTIES" > src/main/resources/application-prod.properties
echo "$APPLICATION_YML" > src/main/resources/application.yml
echo "properties, yml 설정 파일 생성"
./gradlew clean build
echo "jar 빌드"
sudo fuser -k -n tcp 8091 || true
echo "기존 8091 포트 실행 중이던 java 프로세스 확인 후 제거"
nohup java -jar -server -Xmx5g -XX:+UseG1GC -Djava.awt.headless=true -Dspring.profiles.active=dev -Dsvr.nm=DEV -Dfile.encoding=UTF-8 build/libs/*SNAPSHOT.jar 1> /dev/null 2>&1 &
echo "jar 배포"
이제 생성한 yml 파일에 actions가 동작될 스크립트 내용들을 넣어줍니다.
제가 위에서 작성한 예시 코드 내용에 대한 설명은 아래에서 확인할 수 있습니다.
# yml 파일명 지정
ame: Deploy
# dev 브랜치에 push가 발생되게 될 경우 jobs action 실행
on:
push:
branches:
- dev
# 실행될 Action Jobs(여러개의 job 구성 가능)
jobs:
Deploy: # 실행될 Job
runs-on: ubuntu-latest # 실행되는 Job이 어떤 운영체제에서 실행될지 지정 (배포 시 운영되는 해당 서버 운영체제)
steps: # Job에서 실행되는 Step들 (여러개의 step 구성 가능)
- name: CI/CD # 실행되는 Step 명 (아무 명칭이나 지정 가능)
uses: appleboy/ssh-action@v1 # 특정 서버에 접속하기 위한 ssh 접속 외부 프로그램 사용 (github marketplace에서 검색해서 마음에 드는 프로그램 선택 후 지정)
env: # step 실행 환경 설정
# 프로젝트 내부의 git ignore 처리된 예민한 정보를 담고 있는 properties 파일 내용을 가지고 있는 github secret 변수들
APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
APPLICATION_DEV_PROPERTIES: ${{ secrets.APPLICATION_DEV_PROPERTIES }}
APPLICATION_PROD_PROPERTIES: ${{ secrets.APPLICATION_PROD_PROPERTIES }}
APPLICATION_YML: ${{ secrets.APPLICATION_YML }}
with: # 위의 uses에서 호출한 외부 ssh 접속 프로그램 실행 시 필요한 설정 값들 지정 (host, username, password, port)
host: ${{ secrets.HOST }} # 빌드한 프로젝트가 배포될 서버 ip (github secret 변수로 호출)
username: ${{ secrets.USER_NAME }} # 배포할 서버의 접속 계정명 (github secret 변수로 호출)
password: ${{ secrets.PASSWORD }} # 배포할 서버의 접속 비밀번호 (github secret 변수로 호출)
port: ${{ secrets.PORT }} # 배포할 서버의 접속 포트 번호 (github secret 변수로 호출)
# 외부 ssh 프로그램을 사용하면서 git ignore 된 위에서 호출한 환경 변수 내용들을 사용하게끔 지정
envs: APPLICATION_PROPERTIES, APPLICATION_DEV_PROPERTIES, APPLICATION_PROD_PROPERTIES, APPLICATION_YML
script_stop: true # script가 실행 중 중단될 수 있음을 true로 설정
# 본격적인 CI/CD 작업 내용 script 작성
script: | # | 기호를 사용하면 아래처럼 개행 후 여러 개의 script 실행 명령어를 기입 가능
cd /home/onnury/web/Onnury-Mall-BackEnd # 서버에 git clone 받아 풀어둔 해당 프로젝트 경로로 진입
echo "온누리 몰 프로젝트 경로 진입" # 프로젝트 경로에 진입했음을 알리는 용도의 텍스트 출력
rm -rf src/main/resources/application.properties # 기존에 존재했던 프로젝트 내부의 properties 파일 삭제
rm -rf src/main/resources/application-dev.properties # 기존에 존재했던 프로젝트 내부의 properties 파일 삭제
rm -rf src/main/resources/application-prod.properties # 기존에 존재했던 프로젝트 내부의 properties 파일 삭제
rm -rf src/main/resources/application.yml # 기존에 존재했던 프로젝트 내부의 yml 파일 삭제
echo "gitignore 처리된 이전 properties, yml 파일 삭제" # properties, yml 파일 삭제 알림 텍스트 출력
git pull origin dev # git clone 프로젝트에서 최신 내용이 반영된 dev 브랜치 내용을 pull 받아오기
echo "dev 브랜치 pull" # git pull 알림 텍스트 출력
echo "$APPLICATION_PROPERTIES" > src/main/resources/application.properties # 위에서 github secret에서 호출하여 관리하고 있는 properties 파일 내용을 git clone 프로젝트 내부에 생성
echo "$APPLICATION_DEV_PROPERTIES" > src/main/resources/application-dev.properties # 위에서 github secret에서 호출하여 관리하고 있는 properties 파일 내용을 git clone 프로젝트 내부에 생성
echo "$APPLICATION_PROD_PROPERTIES" > src/main/resources/application-prod.properties # 위에서 github secret에서 호출하여 관리하고 있는 properties 파일 내용을 git clone 프로젝트 내부에 생성
echo "$APPLICATION_YML" > src/main/resources/application.yml # 위에서 github secret에서 호출하여 관리하고 있는 yml 파일 내용을 git clone 프로젝트 내부에 생성
echo "properties, yml 설정 파일 생성" # 새롭게 properties, yml 파일 생성 알림 텍스트 출력
./gradlew clean build # clone 프로젝트 빌드 작업 수행
echo "jar 빌드" # 빌드 알림 텍스트 출력
sudo fuser -k -n tcp 8091 || true # 기존에 8091 포트에 실행되고 있는 프로세스가 존재할 경우 제거
echo "기존 8091 포트 실행 중이던 java 프로세스 확인 후 제거" # 제거 알림 텍스트 출력
nohup java -jar -server -Xmx5g -XX:+UseG1GC -Djava.awt.headless=true -Dspring.profiles.active=dev -Dsvr.nm=DEV -Dfile.encoding=UTF-8 build/libs/*SNAPSHOT.jar 1> /dev/null 2>&1 & # 빌드한 파일을 실행하여 프로젝트 무중단 실행
echo "jar 배포" # 빌드한 jar 새롭게 실행 알림 텍스트 호출
## 참고사항 ##
- ${{}} 로 작성된 부분들은 Git Repository의 Settings -> Secrets and variables -> Actions 에서 만들어낸 secret 값들을 말합니다.
- 브랜치 push 하기 이전에 CI /CD 처리될 서버에 들어가서 clone 된 프로젝트 내부에 있는 gradlew 의 접근 허용을 먼저 해줍니다. (접근 허용 명령어 : chmod +x ./gradlew)
(4) Github Secret 환경 변수들 등록
이제 위에서 작성한 yml 파일에 나오는 ${{}} 기호로 감싸진 github secret 변수들을 설정하러 가보겠습니다.
진행 중인 프로젝트의 git repository에 들어가서 Settings > Secrets and variables > Actions 항목에 들어가서 위에서 작성한 yml secret 변수들 명과 동일하게 생성하고 각 변수마다 넣어야될 내용들을 넣어줍니다.
이 Secret 변수들은 한 번 저장되게 되면 아예 확인할 수 없기 때문에 잘 넣어야 합니다.
이제 여기서 만들어낸 secret 변수들이 yml파일에 호출되어 script가 실행되게 되는 것입니다.
(4) 최종 확인
이제 모든 설정과 생성은 마무리 되었으니 이제 commit 후 작성한 내용대로 특정 브랜치에 push를 날려 정상적으로 CI/CD 가 진행되는지 확인해보겠습니다.
작업한 내용들을 commit 후 dev 브랜치에 push를 했더니,
해당 repository의 Actions 메뉴에 진행되었던 Github Actions 내용들이 나온 것을 확인할 수 있습니다.
저는 지금 여러번 진행했기 때문에 여러 개의 Actions 내용들이 나오지만 처음 할 경우 하나의 내용만 나올 것입니다.
가장 최신 Action 내용에 들어가서 확인해보면 정상적으로 script 내용대로 작업이 진행되고 알림 텍스트 또한 나오는 것을 확인할 수 있습니다.
## 참고사항 ##
가령 진행 도중 test에 실패하여 build 가 정상적으로 수행되지 않았다는 에러가 나오면서 action이 정상적으로 실행되지 않거나 타임아웃이 걸릴 경우도 있는데 이것은 프로젝트 내부에 작성한 test 코드들을 확인하여 처리해주면 됩니다.
'기술 창고 > CI, CD' 카테고리의 다른 글
[CI / CD] Jenkins 와 Git 연동 시 발생된 에러 해결 (We couldn't this payload: failed to connect to host) (0) | 2023.02.16 |
---|---|
[CI / CD] Jenkins 와 Git 연동 (0) | 2023.02.15 |
[CI / CD] Jenkins 설치 (0) | 2023.02.08 |
CI / CD (0) | 2023.02.08 |