저는 CI/CD 를 구축하기 위해서 EC2를 사용하였습니다. 어떤 프로젝트를 사용할 지에 따라 사용해야 하는 Computing 서비스가 달라지는데 , 저는 현재 기본적인 CI/CD 구축을 목표로 하고 있으므로 비용적인 부담이 덜하는 EC2를 바탕으로 구현해보았습니다.
일단 CI/CD를 구축하기 위해선 사용하고자 하는 EC2에 기본적인 설정들이 되어있어야 합니다. 저는 Spring Boot 를 사용한 프로젝트에 대해서 CI/CD를 구축할 것이므로 EC2에 JAVA 등이 설치되어 있어야 합니다.
또한 GitHub Actions를 활용하여 CI/CD를 구축할 것이기 때문에 EC2에서 배포 스크립트를 실행할 수 있도록 필요한 권한과 환경을 설정해야 합니다.
EC2에서 프로젝트를 배포하는 방법부터 살표보겠습니다.
1. EC2를 통한 배포
1-1. EC2 생성
ec2 이름 설정(선택)
ec2가 운영될 운영체제를 선택합니다.
어떤 사양의 컴퓨팅을 실행시킬 건지 선택합니다. spring boot 프로젝트가 생각보다 무겁기 때문에 t3.micro(유료)를 설정해줍니다.
또한 키페어를 지정해줍니다. 없다면 새로 생성해줍니다. 새로 생성되면 한 개의 파일이 다운되는데 추후에 원격으로 EC2에 접속할 때 필요하므로 잘 보관해둡니다.
외부에서 해당 EC2에 접속해야하기 때문에 사진과 같이 보안그룹규칙을 추가해줍니다.
제가 안내해드린 것 처럼 설정을 완료했다면 인스턴스 시작 버튼을 눌러 EC2를실행시켜 줍니다.
1-2. EC2 환경설정
EC2에 접속하여 다음 명령어를 통해 필요한 환경들을 설치해줍니다.
sudo apt update
sudo apt install openjdk-17-jdk -y
sudo apt install git
- 우분투 최신 패키지 설정 설정
- 스프링 실행을 위한 자바 17 다운
- git 설치
1-3. git clone
그 후에 ci/cd 하고자 하는 리포지토리의 링크를 clone 합니다.
git clone [깃허브 리포지토리 주소]
만약 clone 하려는 리포지토리가 private이면 닉네임과 password 를 입력해줘야 합니다. 닉네임은 깃허브 자신의 계정 닉네임이고 password 는 다음 링크를 통해 발급 받으시면 됩니다.
Github에서 토큰 발급하기 - 코드잇 스프린트 블로그
GitHub에서 토큰을 발급받는 방법에 대해 알아보세요! 안전하게 깃허브를 사용하는 방법을 배우고, 토큰을 발급받을 수 있어요. | Git, Tech
sprint.codeit.kr
이후 ec2에서 ci/cd 를 진행하는 과정 중에 private 리포지토리를 pull 할 수 있도록 방금 입력한 닉네임과 password가 ec2에 저장할 수 있도록 다음 명령어를 실행시킵니다.
git config --global credential.helper store
현재 저의 깃허브 리토지토리 이름이 Gmenu 라서 Gmenu로 나옵니다. 각자 깃허브에 올라간 프로젝트의 이름이 무엇인지 확인해주세요. 저의 경우 Gmenu 입니다.
1-4. 프로젝트 빌드 및 수행
cd Gemnu - Gmenu 로 이동
ls - 목록 확인
./gradlew clean build - 프로 젝트 빌드
위 코드를 통해서 EC2에 clone된 프로젝트를 빌드해주세요.
그러면 권한이 없기 때문에 빌드를 할 수 없습니다. 다음 명령어를 통해서 권한을 부여해줍니다.
chmod +x ./gradlew
정상적으로 빌드가 되는 것을 볼 수 있습니다.
그 후 다음 명령어를 통해서 서버를 실행시키면 됩니다.
cd build/libs
nohup java -jar jpabook-0.0.1-SNAPSHOT.jar &
2. CI/CD
CI/CD를 사용하지 않는 경우 프로젝트 코드를 수정하거나 기능을 추가할 때 마다 대목차 1의 과정을 거쳐야한다. 너무 번거롭기 때문에 위 과정을 자동화한 방식인 CI/CD 방식을 사용합니다.
그 전에 EC2의 환경설정을 해줘야 하는데 1-1, 1-2, 1-3 을 진행한 후 해당 과정을 진행해주세요.
(만약 1번 과정 다 진행했다면 그냥 진행하셔도 무방합니다 :))
2- 1. workflow 정의
루투 하위에 .gitgub 폴더를 생성하고 생성한 하위에 workflows 라는 폴더를 생성합니다.
workflow는 yml 파일에 정의된 거에 따라 실행됩니다.
이 때 반드시 .github와 workflows 라는 폴더명으로 해야합니다.
yml 파일은 자기가 원하는 이름으로 하면 됩니다.
name: Menu Service Dev CI/CD
on:
push:
branches:
- "main"
jobs:
build-docker-image:
runs-on: ubuntu-latest
steps:
- name: Deploy to server 성공 !
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_PRIVATE_KEY }}
script: |
# 프로젝트 디렉토리로 이동
cd /home/ubuntu/Gmenu
# main 브랜치의 최신 변경사항 가져오기
git pull origin main
# 기존 application.yml 파일 삭제
rm -rf /home/ubuntu/Gmenu/src/main/resources/application.yml
# resources 디렉토리 생성 (없는 경우를 대비)
mkdir -p /home/ubuntu/Gmenu/src/main/resources
# 새로운 application.yml 파일 생성
touch /home/ubuntu/Gmenu/src/main/resources/application.yml
# GitHub Secrets에 저장된 YML 내용을 application.yml에 작성
echo "${{ secrets.YML }}" > /home/ubuntu/Gmenu/src/main/resources/application.yml
# application.yml 파일 권한 확인
ls -l /home/ubuntu/Gmenu/src/main/resources/application.yml
# 8080 포트에서 실행 중인 프로세스 종료 (에러 무시)
sudo fuser -k -n tcp 8080 || true
# gradlew 실행 권한 부여
chmod +x ./gradlew
# 프로젝트 새로 빌드
./gradlew clean build
# 빌드된 jar 파일이 있는 디렉토리로 이동
cd build/libs
# jar 파일 백그라운드 실행 (로그는 output.log에 저장)
nohup java -jar *.SNAPSHOT.jar > ./output.log 2>&1 &
유의사항!!
현제 저의 깃허브 reposiotry의 이름이 Gemu라서 위 workflow에서 정의된 주소는 Gmenu로 돼있습니다. 해당 경로를 자신의 리포지토리에 맞는 경로로 변경해주세요.
ex. repository 의 이름: study
# 프로젝트 디렉토리로 이동
cd /home/ubuntu/study
# main 브랜치의 최신 변경사항 가져오기
git pull origin main
# 기존 application.yml 파일 삭제
rm -rf /home/ubuntu/study/src/main/resources/application.yml
# resources 디렉토리 생성 (없는 경우를 대비)
mkdir -p /home/ubuntu/study/src/main/resources
등등등 자신의 리포지토리에 맞게 모든 경로를 변경해주세요
1. cd /home/ubuntu/Gmenu
- EC2의 프로젝트 디렉토리로 이동합니다
2. git pull origin main
- Github 저장소에서 최신 코드를 가져옵니다
3. 애플리케이션 설정 파일 관리
rm -rf /home/ubuntu/Gmenu/src/main/resources/application.yml
mkdir -p /home/ubuntu/Gmenu/src/main/resources
touch /home/ubuntu/Gmenu/src/main/resources/application.yml
echo "${{ secrets.YML }}" > /home/ubuntu/Gmenu/src/main/resources/application.yml
- 기존 application.yml 파일을 삭제하고
- resources 디렉토리를 생성한 후
- Github Secrets에 저장된 설정 값을 새 application.yml 파일에 작성합니다
4. ls -l /home/ubuntu/Gmenu/src/main/resources/application.yml`
- 생성된 설정 파일의 권한과 상태를 확인합니다
5. sudo fuser -k -n tcp 8080 || true
- 8080 포트에서 실행 중인 기존 애플리케이션을 종료합니다
- || true는 앞의 명령어가 실패하더라도 스크립트 실행을 계속하도록 하는 역할을 합니다.
6. 빌드 및 실행
chmod +x ./gradlew
./gradlew clean build
cd build/libs
nohup java -jar *.SNAPSHOT.jar > ./output.log 2>&1 &
- gradlew에 실행 권한을 부여하고
- 프로젝트를 새로 빌드한 후
- 생성된 jar 파일을 백그라운드에서 실행합니다 (로그는 output.log에 저장)
이 스크립트는 전체적으로 CI/CD 파이프라인의 배포(Deploy) 단계를 자동화하는 역할을 합니다.
2-2. github에 push
위 yml 파일엔 secrets 변수가 설정돼있습니다.
host: ${{ secrets.EC2_HOST }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
echo "${{ secrets.YML }}" > /home/ubuntu/Gmenu/src/main/resources/application.yml
1. host: ${{ secrets.EC2_HOST }}
EC2_HOST 라는 변수를 만들어주고 내용에 사용하고자 하는 EC2 IP 주소를 적어줍니다.
2. key: ${{ secrets.EC2_PRIVATE_KEY }}
EC2_PRIVATE_KEY 라는 변수를 만들어 주고 EC2 를 생성할 때 지정했던 키페어의 모든 내용을 복사 붙여넣기 해줍니다.
3. echo "${{ secrets.YML }}" > /home/ubuntu/Gmenu/src/main/resources/application.yml
기본적으로 리포지토리엔 민감한 정보들이 많은 application.yml 파일을 push 하지않습니다.
따라서 깃허브 리포지토리에 YML 라는 변수를 만들고 프로젝트 application.yml을 복붙한 다음에 넣어줍니다.
2-3. 프로젝트에 workflows를 다 작성했다면 해당 프로젝트를 깃허브에 push
정상적으로 github action이 실행이 됐고 성공적으로 worflow가 진행됐습니다.